<?php

namespace services\patient;

use common\models\base\Drug;
use common\models\base\DrugConfig;
use common\models\patient\DrugRecord;
use common\models\rbac\Action;
use services\base\DrugService;
use services\clinic\UserSurplusService;
use services\dengta\robot\WechatService;
use services\log\MemberOperateLogService;
use services\log\PatientOperateLogService;
use services\marketing\SourceChannelService;
use services\rbac\ActionService;
use Yii;
use common\models\clinic\Project;
use common\models\base\Project as BaseProject;
use common\models\patient\Callback;
use common\models\patient\Consumption;
use common\models\patient\RevisitingRecord;
use common\models\export\Log;
use common\helpers\ExcelHelper;
use common\models\patient\UserAttr;
use common\models\common\Provinces;
use common\models\patient\HistoryRecord;
use common\components\Service;
use common\helpers\CommonHelper;
use common\models\base\PatientDiseases;
use common\models\base\Profession;
use common\models\member\Attr;
use common\models\member\Member;
use common\models\member\Attention;
use common\models\clinic\Clinic;
use common\models\clinic\UserTreatment;
use common\models\patient\BodyParts;
use common\models\base\BodyParts as BaseBodyParts;
use common\models\patient\Tags;
use common\models\patient\User;
use common\models\patient\OperateLog;
use common\models\patient\AllocationRecord;
use common\models\marketing\OutpatientType;
use common\models\marketing\SourceChannel;
use common\models\marketing\ClinicAssess;
use common\models\marketing\EffectType;
use common\models\marketing\RiskType;
use common\models\marketing\CallbackStatus;
use common\models\rbac\Role;
use common\models\rbac\Department;
use common\models\common\Config;
use api\modules\v1\forms\patient\PatientForm;
use services\export\LogService;
use services\baibai\ConfigService;
use services\common\CommonService;
use services\statistics\ManagementReportService;
use yii\db\Expression;
use yii\db\Query;
use yii\web\HttpException;
use Exception;

/**
 * Class UserService
 * @package services\patient
 */
class UserService extends Service
{
    /**
     * 根据ID查找患者信息
     *
     * @param int $id
     * @return User|null
     */
    public function findById(int $id = 0): ?User
    {
        return User::find()->where(['id' => $id])->one();
    }

    /**
     * 查找患者信息
     *
     * @param array $condition
     * @return User|null
     */
    public function findInfo(array $condition = []): ?User
    {
        $query = User::find();

        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
        isset($condition['patient_card_id']) && $query->andWhere(['patient_card_id' => $condition['patient_card_id']]);
        isset($condition['name']) && $query->andWhere(['name' => $condition['name']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        return $query->one();
    }

    /**
     * 查找患者信息
     * @param array $condition
     * @return array
     */
    public function findInfoByDt(array $condition = []): array
    {
        $query = User::find();

        isset($condition['column']) && $query->select($condition['column']);

        isset($condition['project_id']) && $query->andWhere(['project_id' => $condition['project_id']]);
        isset($condition['patient_card_id']) && $query->andWhere(['patient_card_id' => $condition['patient_card_id']]);
        isset($condition['name']) && $query->andWhere(['name' => $condition['name']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        $res = $query->asArray()->one();
        return $res ?: [];
    }

    /**
     * 查找项目患者手机号
     * @param array $condition
     * @return array
     */
    public function getPatientMobiles(array $condition = []): array
    {
         $res = User::find()
            ->select('mobile')
            ->where([
                'project_id' => $condition['project_id'],
                'mobile' => $condition['mobile'],
            ])
            ->column();
         return $res;
    }

    /**
     * 查找患者列表
     *
     * @param array $condition
     * @return array|\yii\db\ActiveRecord[]
     */
    public function findList(array $condition = [])
    {
        $query = User::find();

        // select
        isset($condition['select']) && $query->select($condition['select']);

        // condition
        isset($condition['id']) && $query->andWhere(['id' => $condition['id']]);
        isset($condition['status']) && $query->andWhere(['status' => $condition['status']]);

        // indexBy
        isset($condition['indexBy']) && $query->indexBy($condition['indexBy']);

        return $query->asArray()->all();
    }

    /**
     * 患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $type 【1患者列表（客服）、2患者列表（医助）】
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0, int $type = 1, int $isReturnTotal = 0)
    {
        $params['project_id'] = Yii::$app->params['project_id'];
        $params['outpatient_type_id'] = $params['outpatient_type_id'] ?? 0;
        $params['keywords'] = $params['keywords'] ?? '';
        $params['in_hospital'] = $params['in_hospital'] ?? 0;
        $params['clinic_id'] = $params['clinic_id'] ?? 0;

        $isCheckType = 0;
        if ($type == 1) {
            unset($params['belong_assistant_id']);
            $params['belong_member_id'] = $params['belong_member_id'] ?? 0;

            // 客服可以搜索所有患者(存在搜索条件 同项目管理员权限)
            if (Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO && empty($params['keywords'])) {
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => Yii::$app->params['project_id'],
                ]);

                if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己的患者】
                    $params['belong_member_id'] = Yii::$app->user->identity->member_id;
                } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有客服员工的患者】
                    if (empty($params['belong_member_id'])) {
                        $memberAttrList = Yii::$app->services->attr->findList([
                            'project_id' => Yii::$app->params['project_id'],
                            'department_id' => $attr->department_id,
                            'profession_id' => Profession::ID_CUSTOMER,
                        ]);
                        $params['belong_member_id'] = array_column($memberAttrList, 'member_id');
                    }
                } else {// 项目负责人【项目下所有客服员工】
                    if (empty($params['belong_member_id'])) {
                        $memberAttrList = Yii::$app->services->attr->findList([
                            'project_id' => Yii::$app->params['project_id'],
                            'profession_id' => Profession::ID_CUSTOMER,
                        ]);
                        $params['belong_member_id'] = array_column($memberAttrList, 'member_id');
                    }
                }

                $isCheckType = 1;
            } else {// 超管查看所有【同项目负责人】
                if (empty($params['belong_member_id'])) {
                    $memberAttrList = Yii::$app->services->attr->findList([
                        'project_id' => Yii::$app->params['project_id'],
//                    'profession_id' => Profession::ID_CUSTOMER,
                    ]);
                    $params['belong_member_id'] = array_column($memberAttrList, 'member_id');
                    $params['belong_member_id'][] = '0';
                }
            }
            // 默认展示客服绑定就诊类型
            if (empty($params['keywords']) && empty($params['outpatient_type_id'])) {
                $res['outpatient_type_list'] = CommonService::getOutpatientTypeList(1);
                $params['outpatient_type_id'] = array_column($res['outpatient_type_list'], 'id');
            }
        } else {
            unset($params['belong_member_id']);
            $params['belong_assistant_id'] = $params['belong_assistant_id'] ?? 0;

            if (Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO) {
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => Yii::$app->params['project_id'],
                ]);

                if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己的患者】
                    $params['belong_assistant_id'] = Yii::$app->user->identity->member_id;
                    if ($type == 2 && $attr->profession_id == Profession::ID_MEDICAL && empty($params['clinic_id'])) {
                        $params['clinic_id'] = $attr->clinic_id;
                    }
                } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有医助员工的患者】
                    if (empty($params['belong_assistant_id'])) {
                        $memberAttrList = Yii::$app->services->attr->findList([
                            'project_id' => Yii::$app->params['project_id'],
                            'department_id' => $attr->department_id,
                            'profession_id' => Profession::ID_MEDICAL,
                        ]);
                        $params['belong_assistant_id'] = array_column($memberAttrList, 'member_id');
                    }
                } else {// 项目负责人【项目下所有医助员工】
                    if (empty($params['belong_assistant_id'])) {
                        $memberAttrList = Yii::$app->services->attr->findList([
                            'project_id' => Yii::$app->params['project_id'],
                            'profession_id' => Profession::ID_MEDICAL,
                        ]);
                        $params['belong_assistant_id'] = array_column($memberAttrList, 'member_id');
                    }
                }

                $isCheckType = 1;
            } else {// 超管查看所有【同项目负责人】
                if (empty($params['belong_assistant_id'])) {
                    $memberAttrList = Yii::$app->services->attr->findList([
                        'project_id' => Yii::$app->params['project_id'],
                        'profession_id' => Profession::ID_MEDICAL,
                    ]);
                    $params['belong_assistant_id'] = array_column($memberAttrList, 'member_id');
                }
            }
        }
        $query = $this->createPatientQuery($params, $type);

        $data = $this->getListPageRes($query, $page, $pageSize, [], $isReturnTotal);
        $data['is_check_type'] = $isCheckType;
        return $data;
    }

    /**
     * 公海列表【客服or医助】
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $type 【0客服、1医助】
     * @return array
     */
    public function getSeasListPage(array $params = [], int $page = 0, int $pageSize = 0, int $type = 0)
    {
        $query = $this->createSeasQuery($params, $type);

        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query->asArray()->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 公海列表query
     *
     * @param array $params
     * @param int $type 类型【0客服、1医助】
     * @return \yii\db\ActiveQuery
     */
    private function createSeasQuery(array $params = [], int $type = 0)
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        if ($type == 1) {// 医助
            $query->andWhere(['a.belong_assistant_id' => 0]);
        } else {// 客服

            // 客服列表中只展示全局设置中已设置的就诊类型
            $config = Yii::$app->services->config->findInfo([
                'config_name' => Config::CONFIG_NAME_CUSTOMER_OUTPATIENT,
                'project_id' => $params['project_id']
            ]);
            $ids = [];
            if ($config && $config->config_value) {
                $ids = explode(',', $config->config_value);
            }

            $query->andWhere(['a.outpatient_type_id' => $ids, 'a.belong_member_id' => 0]);
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        } else {
            // 日期
            if (isset($params['start_time']) && $params['start_time']) {
                $query->andWhere(['>=', 'a.last_revisiting_time', strtotime($params['start_time'])]);
            }
            if (isset($params['end_time']) && $params['end_time']) {
                $query->andWhere(['<=', 'a.last_revisiting_time', strtotime($params['end_time'] . ' 23:59:59')]);
            }
        }

        // 来源渠道
        if (isset($params['source_channel_id']) && $params['source_channel_id']) {
            $sourceList = SourceChannelService::getSourceIdAndPidListById($params['source_channel_id']);
            $query->andWhere(['a.source_channel_id' => array_column($sourceList, 'id')]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 门诊
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
        }

        // 诊疗号
        if (isset($params['patient_card_id']) && $params['patient_card_id']) {
            $query->andWhere(['a.patient_card_id' => $params['patient_card_id']]);
        }

        // 病种【一级】
        if (isset($params['patient_diseases_id']) && $params['patient_diseases_id']) {
            $query->andWhere(['a.patient_diseases_id' => $params['patient_diseases_id']]);
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_created_type']) && $params['sort_created_type']) {// 到诊时间
            if ($params['sort_created_type'] == 1) {
                $orderBy = ['a.created_at' => SORT_ASC];
            } elseif ($params['sort_created_type'] == 2) {
                $orderBy = ['a.created_at' => SORT_DESC];
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } elseif (isset($params['sort_updated_type']) && $params['sort_updated_type']) {// 更新时间
            if ($params['sort_updated_type'] == 1) {
                $orderBy = ['a.updated_at' => SORT_ASC];
            } elseif ($params['sort_updated_type'] == 2) {
                $orderBy = ['a.updated_at' => SORT_DESC];
            }
        } else {
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        $query->orderBy($orderBy);

        return $query;
    }

    /**
     * 患者列表query
     *
     * @param array $params
     * @param int $type 类型【1患者列表（客服）、2患者列表（医助）、3抗复发列表】
     * @return \yii\db\ActiveQuery
     */
    private function createPatientQuery(array $params = [], int $type = 1)
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
                'ua.in_hospital_status',
                'COUNT(rr.id) revisiting_time_count', 'MAX(rr.revisting_time) revisting_time'
            ])
            ->leftJoin(UserAttr::tableName() . ' ua', 'a.id = ua.patient_user_id')
            ->leftJoin(RevisitingRecord::tableName() . ' rr', 'rr.project_id = a.project_id AND rr.patient_card_id = a.patient_card_id AND rr.is_sum = '.RevisitingRecord::IS_SUM_YES)
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ])
            ->groupBy('a.id');

        if ($type == 1) {
            if (!isset($params['keywords']) || (isset($params['keywords']) && empty($params['keywords']))) {
                $query->andWhere(['>', 'a.belong_member_id', 0]);
            }
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }

            // 有搜素词时， 加上诊室
            if ($type == 2 || $type == 3) {
                if (Member::IS_SUPER_NO == Yii::$app->user->identity->member->is_super) {
                    $attr = Yii::$app->services->attr->findInfo([
                        'member_id' => Yii::$app->user->identity->member_id,
                        'project_id' => $params['project_id'],
                    ]);
                    if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {
                        // 普通员工, 只展示当前诊室下的
                        $query->andWhere(['a.clinic_id' => $attr->clinic_id]);
                    } else if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {
                        $memberIdArr = Attr::find()
                            ->where([
                                'project_id' => $params['project_id'],
                                'department_id' => $attr->department_id
                            ])
                            ->select('member_id')
                            ->column();

                        $query->andWhere(['a.belong_assistant_id' => $memberIdArr]);
                    }
                }
            }
        } else {
            // 上次到诊日期
            if (isset($params['start_time']) && $params['start_time']) {
                $query->andWhere(['>=', 'rr.revisting_time', strtotime($params['start_time'])]);
            }
            if (isset($params['end_time']) && $params['end_time']) {
                $query->andWhere(['<=', 'rr.revisting_time', strtotime($params['end_time'] . ' 23:59:59')]);
            }
            // 创建日期【初次挂号日期】
            if (isset($params['start_created_time']) && $params['start_created_time']) {
                $query->andWhere([
                    'or',
                    [
                        'and',
                        ['>=', 'a.reg_time', strtotime($params['start_created_time'])],
                        ['>', 'a.reg_time', 0]
                    ],
                    [
                        'and',
                        ['>=', 'a.created_at', strtotime($params['start_created_time'])],
                        ['a.reg_time' => 0]
                    ]
                ]);
            }
            if (isset($params['end_created_time']) && $params['end_created_time']) {
                $query->andWhere([
                    'or',
                    [
                        'and',
                        ['<=', 'a.reg_time', strtotime($params['end_created_time'] . ' 23:59:59')],
                        ['>', 'a.reg_time', 0]
                    ],
                    [
                        'and',
                        ['<=', 'a.created_at', strtotime($params['end_created_time'] . ' 23:59:59')],
                        ['a.reg_time' => 0]
                    ]
                ]);
            }
        }

        // 医助【默认】、客服【有关键词，则排除其他条件】 修改为 同时生效
        //if ($type == 2 || ($type == 1 && empty($params['keywords']))) {
        if (true || empty($params['keywords'])) {
            // 诊室
            if (isset($params['clinic_id']) && $params['clinic_id']) {
                $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
            }

            // 医助归属人
            if (isset($params['belong_assistant_id'])) {
                if (empty($params['belong_assistant_id'])) {
                    $query->andWhere(['>', 'a.belong_assistant_id', 0]);
                } else {
                    $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
                }
            }

            // 归属人
            if (isset($params['belong_member_id'])) {
                if (empty($params['belong_member_id'])) {
                    $query->andWhere(['>', 'a.belong_member_id', 0]);
                } else {
                    $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
                }
            }

            // 就诊类型
            if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
                $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
            }

            // 效果类型
            if (isset($params['effect_type_id']) && $params['effect_type_id']) {
                $query->andWhere(['a.effect_type_id' => $params['effect_type_id']]);
            }

            // 风控类型
            if (isset($params['risk_type_id']) && $params['risk_type_id']) {
                $query->andWhere(['a.risk_type_id' => $params['risk_type_id']]);
            }

            // 诊疗评估类型
            if (isset($params['clinic_assess_id']) && $params['clinic_assess_id']) {
                $query->andWhere(['a.clinic_assess_id' => $params['clinic_assess_id']]);
            }

            // 部位
            if (isset($params['body_parts_ids']) && $params['body_parts_ids']) {
                // 患者部位
                $patientBodyParts = Yii::$app->services->patientBodyParts->findList([
                    'body_parts_id' => explode(',', $params['body_parts_ids']),
                    'status' => BodyParts::STATUS_ENABLE,
                ]);

                // 患者IDs
                $patientUserIds = array_unique(array_column($patientBodyParts, 'patient_user_id'));

                $query->andWhere(['a.id' => $patientUserIds]);
            }

            // 标签
            if (isset($params['tags_ids']) && $params['tags_ids']) {
                // 患者标签
                $patientTags = Yii::$app->services->patientTags->findList([
                    'tags_id' => explode(',', $params['tags_ids']),
                    'status' => Tags::STATUS_ENABLE,
                ]);

                // 患者IDs
                $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

                $query->andWhere(['a.id' => $patientUserIds]);
            }

            // 门诊
            if (isset($params['clinic_id']) && $params['clinic_id']) {
                $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
            }

            // 诊疗号
            if (isset($params['patient_card_id']) && $params['patient_card_id']) {
                $query->andWhere(['a.patient_card_id' => $params['patient_card_id']]);
            }

            // 断诊次数
            if (isset($params['fault_diagnosis_type'])) {
                switch ($params['fault_diagnosis_type']) {
                    case 1:// 1次
                        $query->andWhere(['a.fault_diagnosis_count' => 1]);
                        break;
                    case 2:// 2次
                        $query->andWhere(['a.fault_diagnosis_count' => 2]);
                        break;
                    case 3:// 3次
                        $query->andWhere(['a.fault_diagnosis_count' => 3]);
                        break;
                    case 4:// 3次以上
                        $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                        break;
                    default:
                        break;
                }
            }

            // 是否为抗复发
            if (isset($params['is_anti_relapse'])) {
                $query->andWhere(['a.is_anti_relapse' => $params['is_anti_relapse']]);
            }

            // 下次复诊时间
            if (isset($params['start_next_revisiting_time']) && $params['start_next_revisiting_time']) {
                $query->andWhere(['>=', 'a.next_revisiting_time', strtotime($params['start_next_revisiting_time'])]);
            }
            if (isset($params['end_next_revisiting_time']) && $params['end_next_revisiting_time']) {
                $query->andWhere(['<=', 'a.next_revisiting_time', strtotime($params['end_next_revisiting_time'] . ' 23:59:59')]);
            }

            // 新增患者
            if ((isset($params['start_add_time']) && $params['start_add_time'])
                || (isset($params['end_add_time']) && $params['end_add_time'])) {
                $alloList = Yii::$app->services->patientAllocationRecord->findList([
                    'project_id' => $params['project_id'],
                    'member_id' => Yii::$app->user->identity->member_id,
                    'start_time' => $params['start_add_time'] ?? '',
                    'end_time' => $params['end_add_time'] ?? '',
                ]);
                $query->andWhere(['a.patient_card_id' => array_column($alloList, 'patient_card_id')]);
            }

            // 病种
            if (isset($params['patient_diseases_id']) && is_numeric($params['patient_diseases_id'])) {
                $query->andWhere(['a.patient_diseases_id' => $params['patient_diseases_id']]);
            }

            // 是否住院
            if (isset($params['in_hospital']) && $params['in_hospital'] ) {
                if ($params['in_hospital'] == UserAttr::IS_HOSPITAL_YES) {
                    $query->andWhere(['ua.in_hospital_status' => UserAttr::STATUS_IN_HOSPITAL]);
                } else {
                    $query->andWhere(['ua.in_hospital_status' => [UserAttr::STATUS_NO_HOSPITAL, UserAttr::STATUS_OUT_HOSPITAL]]);
                }
            }

            // 来源渠道
            if (isset($params['source_channel_id']) && $params['source_channel_id']) {
                $sourceChannelId = is_array($params['source_channel_id']) ? $params['source_channel_id'] : explode(',', $params['source_channel_id']);
                $query->andWhere(['a.source_channel_id' => $sourceChannelId]);
            }

            // 城市
            if (isset($params['city_id']) && $params['city_id']) {
                $cityId = is_array($params['city_id']) ? $params['city_id'] : explode(',', $params['city_id']);
                $cityAndChild = Provinces::find()
                    ->select(['id'])
                    ->where(['id' => $cityId])
                    ->orWhere(['pid' => $cityId])
                    ->asArray()
                    ->column();
                $query->andWhere(['a.city_id' => $cityAndChild]);
            }

            // 无微信
            if (isset($params['no_wx_name']) && $params['no_wx_name']) {
                $query->andWhere(['a.wx_name' => '']);
            }
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['revisting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['revisting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if ($type == 1) {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if ($type == 1) {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } elseif (isset($params['sort_anti_type']) && $params['sort_anti_type']) {// 抗复发年限
            if ($params['sort_anti_type'] == 1) {
                $orderBy = ['a.anti_relapse_year' => SORT_ASC];
            } elseif ($params['sort_anti_type'] == 2) {
                $orderBy = ['a.anti_relapse_year' => SORT_DESC];
            }
        } elseif (isset($params['sort_patient_card_id']) && $params['sort_patient_card_id']) {// 诊疗号
            if ($params['sort_patient_card_id'] == 1) {
                $orderBy = ['a.patient_card_id' => SORT_ASC];
            } elseif ($params['sort_patient_card_id'] == 2) {
                $orderBy = ['a.patient_card_id' => SORT_DESC];
            }
        } else {
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        $query->orderBy($orderBy);

        return $query;
    }

    /**
     * 格式化列表数据
     *
     * @param array $data
     * @param array $type 【0公海列表、1患者列表(客服)、2患者列表(医助)】
     * @return array
     */
    public function getListPageFormat(array $data, int $type = 0)
    {
        $list = [];
        // 归属人列表
        $memberList = CommonService::baseRedis('member');
        // 病种列表
        $diseasesList = CommonService::baseRedis('patient_diseases');
        // 来源渠道列表
        $channelList = CommonService::baseRedis('source_channel');
        // 诊断类型列表
        $outPatientTypelList = CommonService::baseRedis('out_patient_type');
        // 诊室列表
        $clinicList = CommonService::baseRedis('clinic');

        foreach ($data as $row) {
            $item = [
                'id' => $row['id'],
                'project_id' => $row['project_id'],
                'name' => $row['name'],
                'age' => $row['age'],
                'gender' => $row['gender'],
                'gender_str' => User::$genders[$row['gender']],
                'patient_card_id' => $row['patient_card_id'],// 诊疗号
                'clinic_name' => $clinicList[$row['clinic_id']]['name'] ?? '',// 诊室
//                'mobile' => $row['mobile'],
                'outpatient_type_id' => $row['outpatient_type_id'],// 就诊类型ID
                'outpatient_name' => $outPatientTypelList[$row['outpatient_type_id']]['outpatient_name'] ?? '',// 就诊类型
                'revisiting_count' => $row['revisiting_count'],// 总复诊次数
                'revisiting_time_count' => $row['revisiting_time_count'] ?? 0,// 复诊次数【筛选日期范围内】
                'callback_count' => $row['callback_count'],// 回访次数
                'missed_days' => $row['missed_days'],// 未到诊天数
                'city_name' => $row['city_name'],// 地区【城市名】
                'source_channel_id' => $row['source_channel_id'],// 来源渠道ID
                'source_name' => $channelList[$row['source_channel_id']]['source_name'] ?? '',// 来源渠道
                'anti_relapse_year' => $row['anti_relapse_year'],
                'anti_relapse_year_str' => $row['anti_relapse_year'] ? $row['anti_relapse_year'] . '年' : '/',
                'in_hospital_status' => $row['in_hospital_status'] ?? '',
//                'wx_name' => $row['wx_name'] ?? '',
                // 创建时间【如果初次挂号时间存在则创建时间展示创建时间，否则展示创建时间】
                'created_at_str' => $row['reg_time'] ? date('Y-m-d', $row['reg_time']) : ($row['created_at'] ? date('Y-m-d', $row['created_at']) : ''),
            ];
            $diseasesName = $diseasesList[$row['patient_diseases_id']]['diseases_name'] ?? '';
            $childDiseasesName = $diseasesList[$row['patient_diseases_child_id']]['diseases_name'] ?? '';
            if ($type == 0) {// 公海
                // 上次来院时间
                $time = $row['reg_time'] > $row['last_revisiting_time'] ? $row['reg_time'] : $row['last_revisiting_time'];

                $item['created_at_str'] = $time ? date('Y-m-d', $time) : '';// 到诊时间
                $item['wx_name'] = $row['wx_name'];// 微信号
                $item['patient_diseases_id'] = $row['patient_diseases_id'];// 病种ID
                $item['diseases_name'] = $diseasesName;// 病种名
                $item['updated_at_str'] = $row['updated_at'] ? date('Y-m-d', $row['updated_at']) : '';// 更新时间
            } else {// 患者列表【医助、客服】
                $row['revisting_time'] = $row['revisting_time'] ?? '';
                $item['last_revisiting_time_str'] = $row['revisting_time'] ? date('Y-m-d', $row['revisting_time']) : '';// 上次复诊时间
                $item['next_revisiting_time_str'] = $row['next_revisiting_time'] ? date('Y-m-d', $row['next_revisiting_time']) : '';// 下次复诊时间
                if ($type == 1) {
                    $item['last_callback_time_str'] = $row['kf_last_callback_time'] ? date('Y-m-d H:i', $row['kf_last_callback_time']) : '';// 客服上次回访时间
                    $item['next_callback_time_str'] = $row['kf_next_callback_time'] ? date('Y-m-d', $row['kf_next_callback_time']) : '';// 客服下次回访时间
                    $item['belong_member_name'] = $row['belong_member_name'] ?: '';
                    $item['diff_day'] = round((time() - $row['kf_next_callback_time']) / 86400);// 过期天数
                } else {
                    $item['last_callback_time_str'] = $row['yz_last_callback_time'] ? date('Y-m-d H:i', $row['yz_last_callback_time']) : '';// 医助上次回访时间
                    $item['next_callback_time_str'] = $row['yz_next_callback_time'] ? date('Y-m-d', $row['yz_next_callback_time']) : '';// 医助下次回访时间
                    $item['belong_member_name'] = $memberList[$row['belong_assistant_id']]['realname'] ?? '';
                    $item['diff_day'] = round((time() - $row['yz_next_callback_time']) / 86400);// 过期天数
                }
                $item['patient_tags_name_arr'] = $row['patient_tags_name'] ? explode(',', $row['patient_tags_name']) : [];// 患者标签数组
                $item['remark'] = $row['remark'];// 备注
                $item['fault_diagnosis_count'] = $row['fault_diagnosis_count'];// 断诊次数
                $item['diseases_name'] = $childDiseasesName ?: ($diseasesName ?: '');// 病种
                $item['callback_id'] = $row['callback_id'] ?? 0;// 回访ID【任务患者列表】
            }

            $list[] = $item;
        }

        return $list;
    }

    /**
     * 分配患者列表
     *
     * @param array $params
     * @return array
     */
    public function getAllotList(array $params = [])
    {
        $query = User::find()->select(['a.id'])->alias('a')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);;

        // 是否为公海用户
        $isSeasPatient = 0;// 是否为公海【0否、1是】
        if (isset($params['is_seas_patient']) && $params['is_seas_patient'] == 1) {
            $isSeasPatient = 1;
            $query->andWhere(['a.belong_member_id' => 0]);
        } else {
            $query->andWhere(['>', 'a.belong_member_id', 0]);
        }

        // 日期
        if (isset($params['start_time']) && $params['start_time']) {
            if ($isSeasPatient) {
                $query->andWhere(['>=', 'a.updated_at', strtotime($params['start_time'])]);
            } else {
                $query->andWhere(['>=', 'a.created_at', strtotime($params['start_time'])]);
            }
        }
        if (isset($params['end_time']) && $params['end_time']) {
            if ($isSeasPatient) {
                $query->andWhere(['<=', 'a.updated_at', strtotime($params['end_time'] . ' 23:59:59')]);
            } else {
                $query->andWhere(['<=', 'a.created_at', strtotime($params['end_time'] . ' 23:59:59')]);
            }
        }

        // 来源渠道
        if (isset($params['source_channel_id']) && $params['source_channel_id']) {
            $query->andWhere(['a.source_channel_id' => explode(',', $params['source_channel_id'])]);
        }

        // 归属人
        if (isset($params['belong_member_id']) && $params['belong_member_id']) {
            $query->andWhere(['a.belong_member_id' => explode(',', $params['belong_member_id'])]);
        }

        // 性别
        if (isset($params['gender']) && $params['gender']) {
            $query->andWhere(['a.gender' => $params['gender']]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => explode(',', $params['outpatient_type_id'])]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 效果类型
        if (isset($params['effect_type_id']) && $params['effect_type_id']) {
            $query->andWhere(['a.effect_type_id' => explode(',', $params['effect_type_id'])]);
        }

        // 风控类型
        if (isset($params['risk_type_id']) && $params['risk_type_id']) {
            $query->andWhere(['a.risk_type_id' => explode(',', $params['risk_type_id'])]);
        }

        // 城市
        if (isset($params['city_id']) && $params['city_id']) {
            $query->andWhere(['a.city_id' => explode(',', $params['city_id'])]);
        }

        // 年龄
        if (isset($params['min_age'])) {
            $query->andWhere(['>=', 'a.age', (int)$params['min_age']]);
        }
        if (isset($params['max_age']) && $params['max_age']) {
            $query->andWhere(['<=', 'a.age', $params['max_age']]);
        }

        // 诊室
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => explode(',', $params['clinic_id'])]);
        }

        $list = $query->asArray()->all();

        return [
            'total' => (int)count($list),
            'list' => $list,
        ];
    }

    /**
     * 患者详情
     *
     * @param int $id
     * @param int $projectId
     * @param int $type
     * @return array|mixed
     */
    public function detail(int $id = 0, int $projectId = 0, int $type = 0)
    {
        // 患者信息
        $patientUser = $this->findById($id);
        if (!$patientUser || $patientUser->project_id != $projectId) {
            return CommonHelper::api(422, '参数错误[id_error]');
        }

        // 患者补充信息
        $patientAttr = UserAttr::findOne(['patient_user_id' => $patientUser->id]);

        // 医助信息
        $member = Yii::$app->services->member->findById($patientUser->belong_assistant_id);

        // 患者绑定部位
        $patientBodyParts = Yii::$app->services->patientBodyParts->findList([
            'patient_user_id' => $id,
            'status' => BodyParts::STATUS_ENABLE,
        ]);
        $bodyPartsIds = array_column($patientBodyParts, 'body_parts_id');

        // 患者标签
        $patientTags = Yii::$app->services->patientTags->findList([
            'patient_user_id' => $id,
            'status' => Tags::STATUS_ENABLE,
        ]);
        $tagsIds = array_column($patientTags, 'tags_id');

        // 就诊类型
        $outpatientType = Yii::$app->services->marketingOutpatientType->findById($patientUser->outpatient_type_id);
        $outpatientName = $outpatientType ? $outpatientType->outpatient_name : '';

        // 诊室
        $clinic = Yii::$app->services->clinic->findById($patientUser->clinic_id);
        $clinicName = $clinic ? $clinic->name : '';

        // 部位
        $bodyParts = Yii::$app->services->bodyParts->findList([
            'select' => ['id', 'body_parts_name'],
            'id' => $bodyPartsIds,
        ]);
        $bodyPartsNameArr = array_column($bodyParts, 'body_parts_name');

        // 标签
        $marketingTags = Yii::$app->services->marketingTags->findList([
            'id' => $tagsIds,
        ]);
        $tagsNameArr = array_column($marketingTags, 'tags_name');

        // 效果类型
        $effectType = Yii::$app->services->marketingEffectType->findById($patientUser->effect_type_id);

        // 风控类型
        $riskType = Yii::$app->services->marketingRiskType->findById($patientUser->risk_type_id);

        // 诊疗评估
        $clinicAssess = Yii::$app->services->marketingClinicAssess->findById($patientUser->clinic_assess_id);

        // 来源渠道
        $sourceChannel = Yii::$app->services->marketingSourceChannel->findById($patientUser->source_channel_id);

        // 病种
        $patientDiseasesName = (string)PatientDiseases::find()->select('diseases_name')->where(['id' => $patientUser->patient_diseases_id])->scalar();
        $patientDiseasesChildName = (string)PatientDiseases::find()->select('diseases_name')->where(['id' => $patientUser->patient_diseases_child_id])->scalar();
        $diseasesName = $patientDiseasesChildName ?: $patientDiseasesName;

        // 消费金额
        $payMoney = Yii::$app->services->patientConsumption->getPatientPayMoney([
            'project_id' => $projectId,
            'patient_card_id' => $patientUser->patient_card_id,
        ]);

        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $projectId,
        ]);
        $isShowCustomer = 0;
        $isShowMedical = 0;
        $isCustomer = 0;// 是否客服
        if ($type == 1) {// 客服
            $isShowCustomer = 1;
        } elseif ($type == 2) {// 医助
            $isShowMedical = 1;
        } else {// 验证
            if ($attr) {
                if ($attr->profession_id == Profession::ID_CUSTOMER) {
                    $isShowCustomer = 1;
                } else {
                    $isShowMedical = 1;
                }
            } else {
                if ($patientUser->yz_next_callback_time > $patientUser->kf_next_callback_time) {
                    $isShowMedical = 1;
                } else {
                    $isShowCustomer = 1;
                }
            }
        }

        if ($attr && $attr->profession_id == Profession::ID_CUSTOMER) {
            $isCustomer = 1;
        }

        // 上次来院时间
        $time = $patientUser->reg_time > $patientUser->last_revisiting_time ? $patientUser->reg_time : $patientUser->last_revisiting_time;

        // 获取是否有关注该患者
        $isFollow = (int)Attention::find()->where(['attention_id' => $id, 'member_id' => Yii::$app->user->identity->member_id])->exists();

        // 是否展示抗复发操作
        $outpatientTypeIds = [
            ManagementReportService::OUTPATIENT_TYPE['referral'],
            ManagementReportService::OUTPATIENT_TYPE['break']
        ];
        $isShowAnti = in_array($patientUser->outpatient_type_id, $outpatientTypeIds) ? 1 : 0;

        // 是否允许显示消费金额
        $actionService = new ActionService();
        $hasPayMoneyLimit = $actionService->isHaveLimit($projectId, Action::FLAG_PATIENT_PAY_MONEY);

        // 查询患者是否绑定微信号
        $wechatService = new WechatService();
        $bindWechat = $wechatService->wechatInfo((int)$id);

        // 返回参数
        return [
            'id' => $patientUser->id,
            'project_id' => $patientUser->project_id,
            'patient_card_id' => $patientUser->patient_card_id,
            'name' => $patientUser->name,
            'age' => $patientUser->age,
            'gender' => $patientUser->gender,
            'gender_str' => User::$genders[$patientUser->gender],
            'belong_assistant_id' => $patientUser->belong_assistant_id,// 医助归属人ID
            'belong_assistant_name' => $member->realname ?? '',// 医助归属人姓名
            'belong_member_id' => $patientUser->belong_member_id,// 归属人ID
            'belong_member_name' => $patientUser->belong_member_name,
            'effect_type_str' => $effectType->effect_name ?? '',
            'risk_type_str' => $riskType->risk_name ?? '',
            'clinic_assess_str' => $clinicAssess->assess_name ?? '',
            'source_name_str' => $sourceChannel->source_name ?? '',
            'mobile' => $patientUser->mobile,
            'city_name' => $patientUser->city_name,
            'address' => $patientUser->address,
            'work_address' => $patientUser->work_address,
            'outpatient_name' => $outpatientName,
            'clinic_name' => $clinicName,
            'body_parts_name_arr' => $bodyPartsNameArr,
            'tags_name_arr' => $tagsNameArr,
            'diseases_name' => $diseasesName,
            'remark' => $patientUser->remark,
            'callback_count' => $patientUser->callback_count,
            'revisiting_count' => $patientUser->revisiting_count,
            'fault_diagnosis_count' => $patientUser->fault_diagnosis_count,
            'is_anti_relapse' => $patientUser->is_anti_relapse,
            // 'next_callback_time_str' => $patientUser->next_callback_time ? date('Y-m-d', $patientUser->next_callback_time) : '',// 下次回访时间
            'kf_next_callback_time_str' => $patientUser->kf_next_callback_time ? date('Y-m-d', $patientUser->kf_next_callback_time) : '',// 客服下次回访时间
            'yz_next_callback_time_str' => $patientUser->yz_next_callback_time ? date('Y-m-d', $patientUser->yz_next_callback_time) : '',// 医助下次回访时间
            'next_revisiting_time_str' => $patientUser->next_revisiting_time ? date('Y-m-d', $patientUser->next_revisiting_time) : '',// 下次复诊时间
            'reg_time_str' => $patientUser->reg_time ? date('Y-m-d', $patientUser->reg_time) : '',// 初次挂号时间
            'revisiting_time_str' => $time ? date('Y-m-d', $time) : '',// 到诊时间
            'created_at_str' => $patientUser->created_at ? date('Y-m-d H:i', $patientUser->created_at) : '',// 创建时间
            'reality_money' => $payMoney,// 消费金额
            'is_show_customer' => $isShowCustomer,
            'is_show_medical' => $isShowMedical,
            'is_customer' => $isCustomer,
            'is_follow' => $isFollow,
            'is_show_anti' => $isShowAnti,
            'is_bind_wechat' => empty($bindWechat['list']) ? 0 : 1,// 是否绑定微信【1是、0否】
            'is_show_reality_moeny' => $hasPayMoneyLimit ? 1 : 0,// 是否允许显示消费金额
            'mobile_history' => $this->getHistoryRecord($id, ['project_id' => $projectId, 'data_type' => HistoryRecord::DATA_TYPE_TEL]),
            'in_hospital_status' => (isset($patientAttr->in_hospital_status) && $patientAttr->in_hospital_status == UserAttr::STATUS_IN_HOSPITAL) ? UserAttr::STATUS_IN_HOSPITAL : UserAttr::STATUS_NO_HOSPITAL,
            'in_hospital_num' => $patientAttr->in_hospital_num ?? 0,
            'wx_name' => $patientUser->wx_name
        ];
    }

    /**
     * 患者编辑详情
     *
     * @param int $id
     * @param int $projectId
     * @param int $editType 类型【1客服、2医助、3其他】
     * @return array|mixed
     */
    public function editInfo(int $id = 0, int $projectId = 0, int $editType = 1)
    {
        // 患者信息
        $patientUser = $this->findById($id);
        if (!$patientUser || $patientUser->project_id != $projectId) {
            return CommonHelper::api(422, '参数错误[id_error]');
        }

        // 患者绑定部位
        $patientBodyParts = Yii::$app->services->patientBodyParts->findList([
            'patient_user_id' => $id,
            'status' => BodyParts::STATUS_ENABLE,
        ]);
        $bodyPartsIds = array_column($patientBodyParts, 'body_parts_id');

        // 患者标签
        $patientTags = Yii::$app->services->patientTags->findList([
            'patient_user_id' => $id,
            'status' => Tags::STATUS_ENABLE,
        ]);
        $tagsIds = array_column($patientTags, 'tags_id');

        // 获取筛选条件
        $isCheckType = 0;
        if (Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO) {
            $isCheckType = 1;
        }
        $isCustomer = 0;// 查询就诊类型条件【1客服绑定就诊类型、0全部】
        $isShowCustomer = 0;// 是否显示客服归属
        $isShowMedical = 0;// 是否显示医助归属
        if ($editType == 1) {// 客服
            $isCustomer = 1;
            $isShowCustomer = 1;
        } elseif ($editType == 2) {// 医助
            $isShowMedical = 1;
        } else {// 其他【判断岗位】
            /*$attr = Yii::$app->services->attr->findInfo([
                'member_id' => Yii::$app->user->identity->member_id,
                'project_id' => $projectId,
            ]);

            if ($attr) {
                if ($attr->profession_id == Profession::ID_MEDICAL) {// 医助
                    $isShowMedical = 1;
                } elseif ($attr->profession_id == Profession::ID_CUSTOMER) {// 客服
                    $isCustomer = 1;
                    $isShowCustomer = 1;
                } else {
                    $isShowMedical = 1;
                    $isShowCustomer = 1;
                }
            } else {
                $isShowMedical = 1;
                $isShowCustomer = 1;
            }*/

            if (Yii::$app->params['is_assistant'] == 1) {// 医助
                $isShowMedical = 1;
            } elseif (Yii::$app->params['is_customer'] == 1) {// 客服
                $isCustomer = 1;
                $isShowCustomer = 1;
            } else {
                $isShowMedical = 1;
                $isShowCustomer = 1;
            }
        }
        $params = [
            'get_source_channel' => 1,
            // 'get_city' => 1,
            //'get_body_parts' => 1,
            'get_body_parts_business' => 1,
            // 'get_member' => 1,
            'get_customer_member' => 1,
            'get_medical_member' => 1,
            'get_effect_type' => 1,
            'get_risk_type' => 1,
            'get_clinic_assess' => 1,
            'get_clinic' => 1,
            'get_callback_status' => 1,
        ];
        $condition = $this->getConditionList($params, $projectId, $isCheckType);
        $condition['outpatient_type_list'] = CommonService::getOutpatientTypeList($isCustomer);
        $condition['tags_list'] = CommonService::getTagsList();
        $condition['patient_diseases_list'] = CommonService::getDiseasesList();

        // 城市列表
        $condition['city_list'] = [];
        $city = Yii::$app->services->provinces->findById($patientUser->city_id);
        if ($city) {
            $condition['city_list'][] = [
                'id' => (string)$city->id,
                'name' => $city->title,
            ];
        }

        // 二级病种
        $condition['patient_diseases_child_list'] = [];
        if ($patientUser->patient_diseases_child_id) {
            $condition['patient_diseases_child_list'] = Yii::$app->services->patientDiseases->findList([
                'select' => ['id', 'diseases_name AS name'],
                'pid' => $patientUser->patient_diseases_id,
                'status' => PatientDiseases::STATUS_ENABLE,
            ]);
            /*$childDiseases = Yii::$app->services->patientDiseases->findById($patientUser->patient_diseases_child_id);
            if ($childDiseases) {
                $condition['patient_diseases_child_list'][] = [
                    'id' => $childDiseases->id,
                    'name' => $childDiseases->diseases_name,
                ];
            }*/
        }

        $isChangeClinic = 0;
        if (Yii::$app->user->identity->member->is_super == Member::IS_SUPER_YES) {
            $isChangeClinic = 1;
        } else {
            $isDepartmentLeader = (int)Attr::find()
                ->where(['member_id' => Yii::$app->user->identity->member_id, 'project_id' => $projectId])
                ->select('is_department_leader')
                ->scalar();
            $isDepartmentLeader == Attr::IS_DEPARTMENT_LEADER_PROJECT && $isChangeClinic = 1;
        }

        return [
            'id' => $patientUser->id,
            'project_id' => $patientUser->project_id,
            'patient_card_id' => $patientUser->patient_card_id,
            'name' => $patientUser->name,
            'age' => $patientUser->age > 0 ? $patientUser->age : null,
            'gender' => (string)$patientUser->gender,
            'birthday' => $patientUser->birthday == '0000-00-00' ? '' : $patientUser->birthday,
            'nickname' => $patientUser->nickname,
            'wx_name' => $patientUser->wx_name,
            'source_channel_id' => (string)$patientUser->source_channel_id,// 来源渠道ID
            'mobile' => $patientUser->mobile,
            'city_id' => (string)$patientUser->city_id,
            'city_name' => $patientUser->city_name,
            'address' => $patientUser->address,
            'patient_diseases_id' => (string)$patientUser->patient_diseases_id,// 病种ID
            'patient_diseases_child_id' => (string)$patientUser->patient_diseases_child_id,// 二级病种ID
            'is_vitiligo_not' => $patientUser->patient_diseases_id == PatientDiseases::VITILIGO_NOT ? true : false, // 判断是不是非白
            'is_first_initially' => $patientUser->outpatient_type_id == ManagementReportService::OUTPATIENT_TYPE['initially'] ? true : false,
            'body_parts_ids' => $bodyPartsIds,// 部位IDs【数组】
            'tags_ids' => $tagsIds,// 标签IDs【数组】
            'belong_assistant_id' => (string)$patientUser->belong_assistant_id,// 患者归属人ID【医助】
            'belong_member_id' => (string)$patientUser->belong_member_id,// 客服归属人ID
            'effect_type_id' => (string)$patientUser->effect_type_id,// 效果类型ID
            'risk_type_id' => (string)$patientUser->risk_type_id,// 风控类型ID
            'clinic_assess_id' => (string)$patientUser->clinic_assess_id,// 诊疗评估ID
            'outpatient_type_id' => (string)$patientUser->outpatient_type_id,// 就诊类型ID
            'clinic_id' => $patientUser->clinic_id ? (string)$patientUser->clinic_id : '',// 诊室ID
            'profession' => $patientUser->profession,// 职业
            // 'next_callback_time' => $patientUser->next_callback_time ? date('Y-m-d', $patientUser->next_callback_time) : '',// 下次回访时间
            'kf_next_callback_time' => $patientUser->kf_next_callback_time ? date('Y-m-d H:i:s', $patientUser->kf_next_callback_time) : '',// 客服下次回访时间
            'yz_next_callback_time' => $patientUser->yz_next_callback_time ? date('Y-m-d H:i:s', $patientUser->yz_next_callback_time) : '',// 医助下次回访时间
            'next_revisiting_time' => $patientUser->next_revisiting_time ? date('Y-m-d H:i:s', $patientUser->next_revisiting_time) : '',// 下次复诊时间
            'remark' => $patientUser->remark,
            'is_show_customer' => $isShowCustomer,
            'is_show_medical' => $isShowMedical,
            'condition' => $condition,
            'is_change_clinic' => $isChangeClinic,  // 是否可以编辑诊室
        ];
    }

    /**
     * 获取筛选条件列表
     *
     * @param array $params [
     *      'get_source_channel' => 1,      // 获取来源渠道【1是、0否】
     *      'get_gender' => 1,              // 获取性别【1是、0否】
     *      'get_city' => 1,                // 获取城市【1是、0否】
     *      'get_body_parts' => 1,          // 获取部位【1是、0否】
     *      'get_member' => 1,              // 获取归属人【0否、1是（项目下所有员工）、2是（项目下所有医助和客服）】
     *      'get_allot_member' => 1,        // 获取分配归属人【1是、0否，项目下医助and客服】
     *      'get_customer_member' => 1,     // 获取客服归属人【1是、0否】
     *      'get_medical_member' => 1,      // 获取医助归属人【1是、0否】
     *      'get_effect_type' => 1,         // 获取效果类型【1是、0否】
     *      'get_risk_type' => 1,           // 获取风控类型【1是、0否】
     *      'get_clinic_assess' => 1,       // 获取诊疗评估【1是、0否】
     *      'get_clinic' => 1,              // 获取诊室【1是、0否】
     *      'get_callback_status' => 1,     // 获取回访状态【1是、0否】
     *      'get_department' => 1,          // 获取部门【1是、0否】
     *      'get_profession' => 1,          // 获取岗位【1是、0否】
     *      'get_role' => 1,                // 获取角色【1是、0否】
     *      'get_hospital' => 1,            // 获取住院【1是、0否】
     * ]
     * @param int $projectId
     * @param int $isCheckType 是否验证【0否（超管）、1验证（非超管，员工身份）】
     * @return array
     */
    public function getConditionList(array $params = [], int $projectId = 0, int $isCheckType = 0)
    {
        $condition = [];

        // 来源渠道
        if (isset($params['get_source_channel']) && $params['get_source_channel'] == 1) {
            $condition['source_channel_list'] = Yii::$app->services->marketingSourceChannel->findList([
                'select' => ['id', 'source_name AS name', 'status'],
                'project_id' => $projectId,
                'status' => [SourceChannel::STATUS_ENABLE, SourceChannel::STATUS_INVALID],
                'pid' => 0,
            ]);
        }

        // 性别
        if (isset($params['get_gender']) && $params['get_gender'] == 1) {
            foreach (User::$genders as $key => $val) {
                $condition['gender_list'][] = [
                    'id' => $key,
                    'name' => $val,
                ];
            }
        }

        // 城市
        if (isset($params['get_city']) && $params['get_city'] == 1) {
            $condition['city_list'] = Yii::$app->services->provinces->getCityList();
        }

        // 部位列表
        if (isset($params['get_body_parts']) && $params['get_body_parts'] == 1) {
            $data = [
                'select' => ['id', 'body_parts_name AS name', 'status'],
                'status' => [BaseBodyParts::STATUS_ENABLE, BaseBodyParts::STATUS_INVALID],
                'type' => BaseBodyParts::TYPE_NORMAL,
            ];
            isset($params['body_parts_id']) && $data['id'] = $params['body_parts_id'];
            $condition['body_parts_list'] = Yii::$app->services->bodyParts->findList($data);
        }

        // 业绩部位(变更为部位一级列表)
        if (isset($params['get_body_parts_business']) && $params['get_body_parts_business'] == 1) {
            $data = [
                'select' => ['id', 'body_parts_name AS name', 'status'],
                'status' => [BaseBodyParts::STATUS_ENABLE, BaseBodyParts::STATUS_INVALID],
                'type' => BaseBodyParts::TYPE_NORMAL,
                'pid' => 0
            ];
            isset($params['body_parts_id']) && $data['id'] = $params['body_parts_id'];
            $condition['body_parts_list'] = Yii::$app->services->bodyParts->findList($data);
        }

        // 归属人
        if (isset($params['get_member'])) {
            $memberList = [];
            if ($params['get_member'] == 1) {
                if ($isCheckType == 0) {
                    $attrList = Yii::$app->services->attr->findList(['project_id' => $projectId]);
                    $memberList = array_column($attrList, 'member_id');
                } else {
                    $attr = Yii::$app->services->attr->findInfo([
                        'member_id' => Yii::$app->user->identity->member_id,
                        'project_id' => $projectId,
                    ]);
                    if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己】
                        $memberList = [Yii::$app->user->identity->member_id];
                    } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有员工】
                        $attrList = Yii::$app->services->attr->findList([
                            'project_id' => $projectId,
                            'department_id' => $attr->department_id,
                        ]);
                        $memberList = array_column($attrList, 'member_id');
                    } else {// 项目负责人【项目下员工】
                        $attrList = Yii::$app->services->attr->findList(['project_id' => $projectId]);
                        $memberList = array_column($attrList, 'member_id');
                    }
                }
            } else {
                if ($isCheckType == 0) {
                    $attrList = Yii::$app->services->attr->findList([
                        'project_id' => $projectId,
                        'profession_id' => [Profession::ID_MEDICAL, Profession::ID_CUSTOMER],
                    ]);
                    $memberList = array_column($attrList, 'member_id');
                } else {
                    $attr = Yii::$app->services->attr->findInfo([
                        'member_id' => Yii::$app->user->identity->member_id,
                        'project_id' => $projectId,
                    ]);
                    if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己】
                        $memberList = [Yii::$app->user->identity->member_id];
                    } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有员工】
                        $attrList = Yii::$app->services->attr->findList([
                            'project_id' => $projectId,
                            'department_id' => $attr->department_id,
                            'profession_id' => [Profession::ID_MEDICAL, Profession::ID_CUSTOMER],
                        ]);
                        $memberList = array_column($attrList, 'member_id');
                    } else {// 项目负责人【项目下员工】
                        $attrList = Yii::$app->services->attr->findList([
                            'project_id' => $projectId,
                            'profession_id' => [Profession::ID_MEDICAL, Profession::ID_CUSTOMER],
                        ]);
                        $memberList = array_column($attrList, 'member_id');
                    }
                }
            }

            $condition['member_list'] = Yii::$app->services->member->findList([
                'select' => ['id', 'realname AS name'],
                'id' => $memberList,
                'status' => Member::STATUS_ENABLE
            ]);
        }

        // 患者分配归属人
        if (isset($params['get_allot_member']) && $params['get_allot_member'] == 1) {
            $attrList = Yii::$app->services->attr->findList([
                'project_id' => $projectId,
                //'profession_id' => [Profession::ID_CUSTOMER, Profession::ID_MEDICAL],
                'profession_id' => [Profession::ID_CUSTOMER],
                'indexBy' => 'member_id',
            ]);
            $memberList = array_column($attrList, 'member_id');

            $condition['member_allot_list'] = Yii::$app->services->member->findList([
                'select' => ['id', 'realname AS name'],
                'id' => $memberList,
                'status' => Member::STATUS_ENABLE
            ]);

            /*$condition['member_allot_list'] = [];
            foreach ($allotList as $row) {
                $condition['member_allot_list'][] = [
                    'id' => $row['id'],
                    'name' => "{$row['name']}-{$attrList[$row['id']]['profession_name']}",
                    'profession_id' => $attrList[$row['id']]['profession_id'],
                ];
            }


            $last_names = array_column($condition['member_allot_list'], 'profession_id');
            array_multisort($last_names, SORT_DESC, $condition['member_allot_list']);*/
        }

        // 客服归属人
        if (isset($params['get_customer_member']) && $params['get_customer_member'] == 1) {
            $memberList = [];
            if ($isCheckType == 0) {// 超管无需验证
                $attrList = Yii::$app->services->attr->findList([
                    'project_id' => $projectId,
                    'profession_id' => Profession::ID_CUSTOMER,
                ]);
                $memberList = array_column($attrList, 'member_id');
            } else {// 非超管，验证身份
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => $projectId,
                ]);
                if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己】
                    $memberList = [Yii::$app->user->identity->member_id];
                } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有员工】
                    $attrList = Yii::$app->services->attr->findList([
                        'project_id' => $projectId,
                        'department_id' => $attr->department_id,
                        'profession_id' => Profession::ID_CUSTOMER,
                    ]);
                    $memberList = array_column($attrList, 'member_id');
                } else {// 项目负责人【项目下员工】
                    $attrList = Yii::$app->services->attr->findList([
                        'project_id' => $projectId,
                        'profession_id' => Profession::ID_CUSTOMER,
                    ]);
                    $memberList = array_column($attrList, 'member_id');
                }
            }

            $condition['member_customer_list'] = Yii::$app->services->member->findList([
                'select' => ['id', 'realname AS name'],
                'id' => $memberList,
                'status' => Member::STATUS_ENABLE
            ]);
        }

        // 医助归属人
        if (isset($params['get_medical_member']) && $params['get_medical_member'] == 1) {
            $memberList = [];
            if ($isCheckType == 0) {
                $attrList = Yii::$app->services->attr->findList([
                    'project_id' => $projectId,
                    'profession_id' => Profession::ID_MEDICAL,
                ]);
                $memberList = array_column($attrList, 'member_id');
            } else {
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => $projectId,
                ]);
                if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {// 普通员工【自己】
                    $memberList = [Yii::$app->user->identity->member_id];
                } elseif ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {// 部门负责人【部门下所有员工】
                    $attrList = Yii::$app->services->attr->findList([
                        'project_id' => $projectId,
                        'department_id' => $attr->department_id,
                        'profession_id' => Profession::ID_MEDICAL,
                    ]);
                    $memberList = array_column($attrList, 'member_id');
                } else {// 项目负责人【项目下员工】
                    $attrList = Yii::$app->services->attr->findList([
                        'project_id' => $projectId,
                        'profession_id' => Profession::ID_MEDICAL,
                    ]);
                    $memberList = array_column($attrList, 'member_id');
                }
            }

            $condition['member_medical_list'] = Yii::$app->services->member->findList([
                'select' => ['id', 'realname AS name'],
                'id' => $memberList,
                'status' => Member::STATUS_ENABLE
            ]);
        }

        // 效果类型
        if (isset($params['get_effect_type']) && $params['get_effect_type'] == 1) {
            $condition['effect_type_list'] = Yii::$app->services->marketingEffectType->findList([
                'select' => ['id', 'effect_name AS name', 'status'],
                'project_id' => $projectId,
                'status' => [EffectType::STATUS_ENABLE, EffectType::STATUS_INVALID],
            ]);
        }

        // 风控类型
        if (isset($params['get_risk_type']) && $params['get_risk_type'] == 1) {
            $condition['risk_type_list'] = Yii::$app->services->marketingRiskType->findList([
                'select' => ['id', 'risk_name AS name', 'status'],
                'project_id' => $projectId,
                'is_builtin' => 2,
                'status' => [RiskType::STATUS_ENABLE, RiskType::STATUS_INVALID],
            ]);
        }

        // 诊疗评估类型
        if (isset($params['get_clinic_assess']) && $params['get_clinic_assess'] == 1) {
            $condition['clinic_assess_list'] = Yii::$app->services->marketingClinicAssess->findList([
                'select' => ['id', 'assess_name AS name', 'status'],
                'project_id' => $projectId,
                'status' => [ClinicAssess::STATUS_ENABLE, ClinicAssess::STATUS_INVALID],
            ]);
        }

        // 诊室
        if (isset($params['get_clinic']) && $params['get_clinic'] == 1) {
            $condition['clinic_list'] = Yii::$app->services->clinic->findList([
                'select' => ['id', 'name'],
                'project_id' => $projectId,
                'status' => Clinic::STATUS_ENABLE,
            ]);
        }

        // 回访状态
        if (isset($params['get_callback_status']) && $params['get_callback_status'] == 1) {
            $condition['callback_status_list'] = Yii::$app->services->marketingCallbackStatus->findList([
                'select' => ['id', 'callback_name AS name', 'status'],
                // 'project_id' => $projectId,
                'status' => [CallbackStatus::STATUS_ENABLE, CallbackStatus::STATUS_INVALID],
            ]);
        }

        // 部门
        if (isset($params['get_department']) && $params['get_department'] == 1) {
            $condition['department_list'] = Yii::$app->services->department->findList([
                'select' => ['id', 'name'],
                'project_id' => $projectId,
                'status' => Department::STATUS_ENABLE,
            ]);
        }

        // 岗位
        if (isset($params['get_profession']) && $params['get_profession'] == 1) {
            $condition['profession_list'] = Yii::$app->services->profession->findList([
                'select' => ['id', 'name'],
                'status' => Profession::STATUS_ENABLE,
            ]);
        }

        // 角色
        if (isset($params['get_role']) && $params['get_role'] == 1) {
            $condition['role_list'] = Yii::$app->services->role->findList([
                'select' => ['id', 'name'],
                'other' => [
                    'and',
                    ['status' => Role::STATUS_ENABLE],
                    [
                        'or',
                        [
                            'and',
                            ['type' => Role::TYPE_NOMAL],
                            ['project_id' => $projectId],
                        ],
                        ['type' => Role::TYPE_INLAY],
                    ],
                ],
            ]);
        }

        // 住院
        if (isset($params['get_hospital']) && $params['get_hospital'] == 1) {
            $condition['hospital'] = [
                [
                    "value" => UserAttr::IS_HOSPITAL_YES,
                    "label" => '住院'
                ],
                [
                    "value" => UserAttr::IS_HOSPITAL_NO,
                    "label" => '未住院'
                ]
            ];
        }
            return $condition;
    }


    /**
     * 导医,创建时间为今天的所有数据,可以自己选择日期
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function doctorGuideList(array $params = [], int $page = 0, int $pageSize = 0)
    {
        $query = User::find()
            ->select([
                'a.*', 'a.reg_time as created_at',
            ])
            ->alias('a')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        //$query->andWhere(['>', 'a.belong_member_id', 0]);

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        } else {
            // 日期
            if (isset($params['start_time']) && $params['start_time']) {
                $query->andWhere(['>=', 'a.reg_time', strtotime($params['start_time'])]);
            } else {
                $query->andWhere(['>=', 'a.reg_time', strtotime(date('Y-m-d') . ' 00:00:00')]);
            }
            if (isset($params['end_time']) && $params['end_time']) {
                $query->andWhere(['<=', 'a.reg_time', strtotime($params['end_time'] . ' 23:59:59')]);
            } else {
                $query->andWhere(['<=', 'a.reg_time', strtotime(date('Y-m-d') . ' 23:59:59')]);
            }
        }

        // 来源渠道
        if (isset($params['source_channel_id']) && $params['source_channel_id']) {
            $sourceList = SourceChannelService::getSourceIdAndPidListById($params['source_channel_id']);
            $query->andWhere(['a.source_channel_id' => array_column($sourceList, 'id')]);
        }

        // 病种类型
        if (isset($params['patient_diseases_id']) && $params['patient_diseases_id']) {
            $query->andWhere(['a.patient_diseases_id' => $params['patient_diseases_id']]);
        }

        // 门诊
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
        }

        // 排序
        $orderBy = ['a.reg_time' => $params['sort'] == 2 ? SORT_ASC : SORT_DESC];
        $orderBy['a.id'] = SORT_DESC;

        $query->orderBy($orderBy);

        // 总数
        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query->asArray()->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 格式化导医数据
     *
     * @param array $data
     * @return array
     */
    public function doctorGuideListFormat(array $data = [])
    {
        $list = [];
        // 病种列表
        $diseasesList = CommonService::baseRedis('patient_diseases');
        // 诊室列表
        $clinicList = CommonService::baseRedis('clinic');
        // 来源渠道列表
        $channelList = CommonService::baseRedis('source_channel');
        foreach ($data as $row) {
            $diseasesName = $diseasesList[$row['patient_diseases_id']]['diseases_name'] ?? '';
            $childDiseasesName = $diseasesList[$row['patient_diseases_child_id']]['diseases_name'] ?? '';
            $list[] = [
                'id' => $row['id'],
                'project_id' => $row['project_id'],
                'patient_card_id' => $row['patient_card_id'],
                'name' => $row['name'],
                'age' => $row['age'],
                'gender' => $row['gender'],
                'gender_str' => User::$genders[$row['gender']],
                'clinic_name' => $clinicList[$row['clinic_id']]['name'] ?? '',
                'created_at_str' => $row['reg_time'] ? date('Y-m-d H:i', $row['reg_time']) : '',
                'mobile' => $row['mobile'] ? preg_replace('/(\d{3})\d{4}(\d{4})/', '$1****$2', $row['mobile']) : $row['mobile'],
                'city_name' => $row['city_name'],
                'diseases_name' => $childDiseasesName ?: $diseasesName,
                'source_name' => $channelList[$row['source_channel_id']]['source_name'] ?? '',// 来源渠道
            ];
        }

        return $list;
    }


    /**
     * 治疗列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getTreatmentList(array $params = [], int $page = 0, int $pageSize = 0)
    {
        $projectId = Yii::$app->params['project_id'];
        $query1 = UserTreatment::find()
            ->select([
                'id',
                'type',
                'clinic_project_id',
                new Expression('(recently_clinic_num + recently_surplus_num) clinic_num'),
                'clinic_project_name',
                'total_num',
                'help_num',
                'operate_name',
                'recently_clinic_time',
                'created_at',
                new Expression('1 data_type'),
            ])
            ->where(['patient_card_id' => $params['patient_card_id'], 'project_id' => $projectId]);

        $query2 = DrugRecord::find()
            ->alias('a')
            ->select([
                'a.id',
                'a.type',
                'a.drug_config_id clinic_project_id',
                'a.operate_num clinic_num',
                new Expression("CONCAT_WS('_|#', b.drug_id, b.drug_type, b.drug_volume, b.water_type, b.water_volume, d.drug_name, d.drug_unit) clinic_project_name"),
                new Expression("'/' total_num"),
                new Expression("'/' help_num"),
                'm.realname operate_name',
                'a.created_at recently_clinic_time',
                'a.created_at',
                new Expression('2 data_type'),
            ])
            ->innerJoin(DrugConfig::tableName() . ' b', 'a.drug_config_id = b.id')
            ->leftJoin(Drug::tableName() . ' d', 'b.drug_id = d.id')
            ->innerJoin(Member::tableName() . ' m', 'a.operate_id = m.id')
            ->where(['a.patient_user_id' => $params['patient_user_id']]);

        $queryAll = $query1->union($query2, true);
        $query = (new Query())->from(['c' => $queryAll]);


        if ($params['clinic_project_id'] && $params['data_type']) {
            $query->andWhere([
                'c.clinic_project_id' => $params['clinic_project_id'],
                'c.data_type' => $params['data_type'],
            ]);
        }

        if ($params['clinic_date']) {
            $sTime = strtotime(date('Ymd', strtotime($params['clinic_date'])));
            $eTime = $sTime + 86399;
            $query->andWhere(['between', 'c.recently_clinic_time', $sTime, $eTime]);
        }

        $total = $query->count();

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $order = [
            'c.created_at' => SORT_DESC,
            'c.id' => SORT_DESC,
        ];
        $list = $query->orderBy($order)->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 格式化治疗信息列表
     *
     * @param array $data
     * @return array
     */
    public function getTreatmentListFormat(array $data = [])
    {
        $list = [];
        foreach ($data as $row) {
            if ($row['data_type'] == 2) {// 输液大厅
                // 治疗项目
                $data = explode('_|#', $row['clinic_project_name']);
                $drugId = $data[0];
                $drugType = $data[1];
                $drugVolume = $data[2];
                $waterType = $data[3];
                $waterVolume = $data[4];
                $drugName = $data[5] ?? null;
                $drugUnit = $data[6] ?? null;
                $clinicProjectName = DrugService::getDrugContent($drugId, $drugName, $drugUnit, $drugType, $drugVolume, $waterType, $waterVolume);
                // 类型
                $typeStr = DrugRecord::$type[$row['type']] ?? '';
            } else {// 治疗项目
                $clinicProjectName = $row['clinic_project_name'];
                $typeStr = UserTreatment::$type[$row['type']] ?? '';
            }

            $item = [
                'id' => $row['id'],// 治疗ID
//                'patient_card_id' => $row['patient_card_id'],// 诊疗号
//                'clinic_project_id' => $row['clinic_project_id'],// 治疗项目id
                'clinic_project_name' => $clinicProjectName,// 治疗项目
                'clinic_num' => $row['clinic_num'],// 本次使用数量
                'total_num' => $row['total_num'],// 本次剩余数
                'help_num' => $row['help_num'],// 本次剩余数
                'type' => $row['type'],
                'type_str' => $typeStr,
                'operate_name' => $row['operate_name'],// 操作人
//                'profession_name' => $row['operate_profession'] ? $row['operate_profession'] : '',// 岗位名称
                'recently_clinic_time_str' => $row['recently_clinic_time'] ? date('Y-m-d H:i', $row['recently_clinic_time']) : '',
                'data_type' => $row['data_type'],
            ];

            $list[] = $item;
        }

        return $list;
    }

    /**
     * 统计患者初诊年份
     *
     * @param array $param
     * @return array|\yii\db\ActiveRecord[]
     */
    public function getUserRegTimeYearList(array $param = [])
    {
        $query = User::find()->select(new Expression("FROM_UNIXTIME(reg_time, '%Y') AS year"))
            ->groupBy('year')
            ->orderBy(['reg_time' => SORT_DESC]);

        if (isset($param['project_id']) && $param['project_id']) {
            $query->where(['project_id' => $param['project_id']]);
        }

        $query->andWhere(['>', 'reg_time', 0]);

        return $query->asArray()->all();
    }

    /**
     * 编辑患者
     *
     * @param PatientForm $model
     * @param int $type 编辑类型【1客服、2医助、3其他】
     * @return array|mixed
     */
    public function edit(PatientForm $model, int $type = 1)
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            $belongMember = $model->getBelongMember();// 归属人信息
            $patient = $model->getPatient();// 患者原信息
            $city = $model->getCity();// 城市信息
            // 患者原信息
            $oldPatient = new User();
            $oldPatient->setAttributes($patient->getAttributes());

            // 1.更新患者
            $patient->name = $model->name;
            $patient->birthday = $model->birthday ?: '0000-00-00';
            $patient->age = $model->age ?: 0;
            $patient->nickname = $model->nickname ?: '';
            $patient->wx_name = $model->wx_name ?: '';
            $patient->source_channel_id = $model->source_channel_id ?: 0;
            $patient->gender = $model->gender ?: 0;
            $patient->mobile = $model->mobile ?: '';
            $patient->city_id = $model->city_id ?: 0;
            $patient->city_name = $city->title ?? '';
            $patient->address = $model->address ?: '';
            $patient->patient_diseases_id = $model->patient_diseases_id ?: 0;
            $patient->patient_diseases_child_id = $model->patient_diseases_child_id ?: 0;
            $patient->patient_body_parts_name = $model->getPatientBodyPartsName();
            $patient->patient_tags_name = $model->getPatientTagsName();
            $patient->effect_type_id = $model->effect_type_id ?: 0;
            $patient->risk_type_id = $model->risk_type_id ?: 0;
            $patient->clinic_assess_id = $model->clinic_assess_id ?: 0;
            $patient->outpatient_type_id = $model->outpatient_type_id ?: 0;
            $patient->clinic_id = $model->clinic_id ?: 0;
            $patient->profession = $model->profession ?: '';
            if ($type == 1) {// 客服
                $patient->belong_member_id = $model->belong_member_id ?: 0;
                $patient->belong_member_name = $belongMember ? $belongMember->realname : '';
            } elseif ($type == 2) {// 医助
                $patient->belong_assistant_id = $model->belong_assistant_id ?: 0;
            } else {// 其他
                $patient->belong_member_id = $model->belong_member_id ?: 0;
                $patient->belong_member_name = $belongMember ? $belongMember->realname : '';
                $patient->belong_assistant_id = $model->belong_assistant_id ?: 0;
            }
            // 完善度
            $patient->degree_num = $this->computeDegreeNum([
                'name' => $patient->name,
                'mobile' => $patient->mobile,
                'gender' => $patient->gender,
                'city_id' => $patient->city_id,
                'patient_diseases_id' => $patient->patient_diseases_id,
                'body_parts_ids' => $patient->patient_body_parts_name ? 1 : 0,
                'patient_tags_name' => $patient->patient_tags_name,
                'effect_type_id' => $patient->effect_type_id,
                'risk_type_id' => $patient->risk_type_id,
            ]);
            $patient->saveAndCheckResult();

            // 1-2.患者分配记录
            if (($type == 1 || $type == 3) && $patient->belong_member_id && $oldPatient->belong_member_id != $patient->belong_member_id) {
                $allocationRecord = new AllocationRecord();
                $allocationRecord->project_id = $model->project_id;
                $allocationRecord->patient_card_id = $patient->patient_card_id;
                $allocationRecord->member_id = $patient->belong_member_id;
                $allocationRecord->current_profession_id = AllocationRecord::CURRENT_PROFESSION_ID_CUSTOMER;
                $allocationRecord->operate_id = Yii::$app->user->identity->member_id;
                $allocationRecord->saveAndCheckResult();
            }
            if (($type == 2 || $type == 3) && $patient->belong_assistant_id && $oldPatient->belong_assistant_id != $patient->belong_assistant_id) {
                $allocationRecord = new AllocationRecord();
                $allocationRecord->project_id = $model->project_id;
                $allocationRecord->patient_card_id = $patient->patient_card_id;
                $allocationRecord->member_id = $patient->belong_assistant_id;
                $allocationRecord->current_profession_id = AllocationRecord::CURRENT_PROFESSION_ID_MEDICAL;
                $allocationRecord->operate_id = Yii::$app->user->identity->member_id;
                $allocationRecord->saveAndCheckResult();
            }

            // 2-1.新增部位
            foreach ($model->getAddBodyPartsIds() as $row) {
                $patientBodyParts = Yii::$app->services->patientBodyParts->findInfo([
                    'patient_user_id' => $model->id,
                    'body_parts_id' => $row,
                ]);
                if (!$patientBodyParts) {
                    $patientBodyParts = new BodyParts();
                }
                $patientBodyParts->patient_user_id = $model->id;
                $patientBodyParts->body_parts_id = $row;
                $patientBodyParts->status = BodyParts::STATUS_ENABLE;
                $patientBodyParts->save();
            }
            // 2-2.删除部位
            BodyParts::deleteAll(['patient_user_id' => $model->id, 'body_parts_id' => $model->getDeleteBodyPartsIds()]);

            // 3-1.新增标签
            foreach ($model->getAddTagsIds() as $row) {
                $patientTags = Yii::$app->services->patientTags->findInfo([
                    'patient_user_id' => $model->id,
                    'tags_id' => $row,
                ]);
                if (!$patientTags) {
                    $patientTags = new Tags();
                }
                $patientTags->patient_user_id = $model->id;
                $patientTags->tags_id = $row;
                $patientTags->status = Tags::STATUS_ENABLE;
                $patientTags->save();
            }
            // 3-2.删除标签
            Tags::deleteAll(['patient_user_id' => $model->id, 'tags_id' => $model->getDeleteTagsIds()]);

            // 4-1.患者编辑日志
            PatientOperateLogService::create($model->project_id, $patient->id, OperateLog::ACTION_TYPE_PATIENT_UPDATE, PatientOperateLogService::getPatientChangeLog($patient, $oldPatient));
            // 4-2.记录手机号编辑历史记录
            PatientHistoryRecordService::create($model->project_id, $patient->id, HistoryRecord::DATA_TYPE_TEL, $oldPatient->mobile, $patient->mobile);
            // 4-3.添加微信号历史记录
            PatientHistoryRecordService::create($model->project_id, $patient->id, HistoryRecord::DATA_TYPE_WECHAT, $oldPatient->wx_name, $patient->wx_name);
            // 4-4.用户操作日志
            MemberOperateLogService::createPatientLog($model, $patient, $oldPatient);

            // 5.手机号匹配更新灯塔患者诊疗号、诊断类型【更改为病种变化时才同步到灯塔】
            $projectInfo = BaseProject::findOne($patient->project_id);
            if ($projectInfo
                && ($patient->patient_diseases_id != $oldPatient->patient_diseases_id || $patient->patient_diseases_child_id != $oldPatient->patient_diseases_child_id)
            ) {// 病种修改时同步更新到灯塔
                // 病种信息
                $diseaseName = PatientDiseases::find()
                    ->select('diseases_name')
                    ->where(['id' => array_filter([$patient->patient_diseases_id, $patient->patient_diseases_child_id])])
                    ->column();
                $url = Yii::$app->params['dengta_host'] . '/v1/statistics/patient-arrive-report/by-update-info';
                $data = [
                    'project_sx' => $projectInfo->name_sx,
                    'patient_card_id' => $patient->patient_card_id,
                    'mobile' => $patient->mobile,
                    'user_name' => $patient->name,
                    'city_area' => $patient->city_name,
                    'diagnosis_type' => !empty($diseaseName) ? implode('/', $diseaseName) : '',
                    'revisiting_time' => $patient->last_revisiting_time
                ];
                CommonHelper::https_request($url, $data);
            }
            $transaction->commit();

            return ['id' => $model->id];
        } catch (\Exception $e) {
            $transaction->rollBack();

            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 编辑患者备注
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function editRemark(PatientForm $model)
    {
        try {
            // 1.更新患者
            $patient = $model->getPatient();
            // 患者原信息
            $oldPatient = new User();
            $oldPatient->setAttributes($patient->getAttributes());
            $patient->remark = $model->remark ?: '';
            $patient->saveAndCheckResult();

            // 2.用户操作日志
            MemberOperateLogService::createPatientLog($model, $patient, $oldPatient);

            return ['id' => $model->id];
        } catch (\Exception $e) {
            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 分配归属人
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function editBelongMember(PatientForm $model)
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 患者信息
            $patient = $model->getPatient();
            $oldPatient = new User();
            $oldPatient->setAttributes($patient->getAttributes());
            // 1.更新患者
            $patient->belong_member_id = $model->belong_member_id;
            $patient->belong_member_name = $model->getBelongMember()->realname ?? '';
            $patient->saveAndCheckResult();

            // 2.患者分配记录
            $attr = Yii::$app->services->attr->findInfo([
                'member_id' => $model->belong_member_id,
                'project_id' => $model->project_id,
            ]);
            $allocationRecord = new AllocationRecord();
            $allocationRecord->project_id = $model->project_id;
            $allocationRecord->patient_card_id = $patient->patient_card_id;
            $allocationRecord->member_id = $model->belong_member_id;
            $allocationRecord->current_profession_id = $attr->profession_id == Profession::ID_CUSTOMER ? AllocationRecord::CURRENT_PROFESSION_ID_CUSTOMER : AllocationRecord::CURRENT_PROFESSION_ID_MEDICAL;
            $allocationRecord->operate_id = Yii::$app->user->identity->member_id;
            $allocationRecord->created_at = Yii::$app->params['time'];
            $allocationRecord->save();
            // 3.用户操作日志
            MemberOperateLogService::createPatientLog($model, $patient, $oldPatient);

            $transaction->commit();

            return ['id' => $model->id];
        } catch (\Exception $e) {
            $transaction->rollBack();

            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 编辑抗复发状态
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function editAnti(PatientForm $model)
    {
        try {
            $patient = $model->getPatient();

            // 复诊
            $outpatientTypeId = ManagementReportService::OUTPATIENT_TYPE['referral'];

            // 1.更新患者
            $attributes = [
                'is_anti_relapse' => $model->is_anti_relapse,
                // 'outpatient_type_id' => $outpatientTypeId,
            ];
            // 患者为断诊状态，修改为复诊
            if ($patient->outpatient_type_id == ManagementReportService::OUTPATIENT_TYPE['break']) {
                $attributes['outpatient_type_id'] = $outpatientTypeId;
            }
            User::updateAll($attributes, ['id' => $model->id]);

            return ['id' => $model->id];
        } catch (\Exception $e) {
            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 编辑抗复发年限
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function editAntiYear(PatientForm $model)
    {
        try {
            // 1.更新患者
            $attributes = [
                'anti_relapse_year' => $model->anti_relapse_year,
            ];
            User::updateAll($attributes, ['id' => $model->id]);

            return ['id' => $model->id];
        } catch (\Exception $e) {
            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 批量分配归属人
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function editBatchBelongMember(PatientForm $model)
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            $ids = array_unique(explode(',', $model->ids));
            $belongMemberIds = array_unique(explode(',', $model->belong_member_ids));

            // 平均分人数【一个归属人分到患者数  余数=0平分，余数>0不足归属人少1个患者】
            $newIds = array_chunk($ids, ceil(count($ids) / count($belongMemberIds)));
            // 患者列表
            $memberList = $model->getMemberList();
            // 分配归属人=>患者IDs
            $allotList = [];
            foreach ($newIds as $row) {
                // 取出队列第一个归属人
                $memberId = array_shift($belongMemberIds);
                // 1.更新患者
                if ($model->check_type == 2) {
                    $attributes = ['belong_assistant_id' => $memberId];
                } else {
                    $attributes = [
                        'belong_member_id' => $memberId,
                        'belong_member_name' => $memberList[$memberId]['realname'] ?? '',
                    ];
                }
                User::updateAll($attributes, ['id' => $row]);

                // 2.患者分配记录
                $patientUserList = self::findList([
                    'id' => $row,
                    'indexBy' => 'id',
                ]);
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => $model->check_type == 2 ? $attributes['belong_assistant_id'] : $attributes['belong_member_id'],
                    'project_id' => $model->project_id,
                ]);
                $insertData = [];
                foreach ($row as $id) {
                    $insertData[] = [
                        $model->project_id,
                        $patientUserList[$id]['patient_card_id'],
                        $attr->member_id,
                        $attr->profession_id == Profession::ID_CUSTOMER ? AllocationRecord::CURRENT_PROFESSION_ID_CUSTOMER : AllocationRecord::CURRENT_PROFESSION_ID_MEDICAL,
                        Yii::$app->user->identity->member_id,
                        Yii::$app->params['time'],
                    ];
                }
                Yii::$app->db->createCommand()
                    ->batchInsert(
                        AllocationRecord::tableName(),
                        ['project_id', 'patient_card_id', 'member_id', 'current_profession_id', 'operate_id', 'created_at'],
                        $insertData
                    )
                    ->execute();
                // 分配参数
                $allotList[$memberId] = [
                    'member_id' => $memberId,
                    'member_name' => $memberList[$memberId]['realname'] ?? '',
                    'patient_ids' => $row,
                ];
            }
            // 2.用户操作日志
            MemberOperateLogService::createPatientLog($model, null, null, ['allot_data' => $allotList]);

            $transaction->commit();

            return ['ids' => $ids];
        } catch (\Exception $e) {
            $transaction->rollBack();

            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 更新未到诊天数
     *
     * @param PatientForm $model
     * @return array|mixed
     */
    public function updateMissedDays()
    {
        // 患者列表
        $userList = $this->findList([
            'select' => ['id', 'last_revisiting_time', 'reg_time'],
            'status' => [User::STATUS_ENABLE, User::STATUS_INVALID],
        ]);

        // 更新未到诊天数
        $updateId = [];
        foreach ($userList as $row) {
            if ($row['last_revisiting_time'] > 0) {
                $diffTime = Yii::$app->params['time'] - $row['last_revisiting_time'];
            } else {
                $diffTime = Yii::$app->params['time'] - $row['reg_time'];
            }

            $day = ceil($diffTime / 86400);
            User::updateAll(['missed_days' => $day], ['id' => $row['id']]);

            $updateId[] = $row['id'];
        }

        return ['ids' => $updateId];
    }

    /**
     * 'count_patient' => 总患者,
     * 'today_patient_add' => 今日新增患者,
     * 'count_unfollow' => 总过期未回访数
     * 'count_unfollow_week' => 本周过期未回访数,
     * 'count_outpatient_type' => 总复诊人数,
     * 'count_outpatient_type_week' => 本周总复诊人数
     * @param array $params
     * @return array
     */
    public function patientUser(array $params = [])
    {
        $project_id = $params['project_id'];

        // 各类别时间范围筛选
        $patientTime = isset($params['patient_num_time']) ? $params['patient_num_time'] : 'day';// 新增患者
        $unfollowTime = isset($params['unfollow_time']) ? $params['unfollow_time'] : 'month';// 未回访
        $outpatientTypeTime = isset($params['outpatient_type_time']) ? $params['outpatient_type_time'] : 'week';// 复诊
        $preArrivalTime = isset($params['pre_arrival_time']) ? $params['pre_arrival_time'] : 'week';// 预到
        $unArrivalTime = isset($params['un_arrival_time']) ? $params['un_arrival_time'] : 'week';// 过期未到

        $patient_time = self::getChooseTime($patientTime, 1, 0);// 新增患者时间范围
        $unfollow_time = self::getChooseTime($unfollowTime, 0, 0);// 未回访时间范围
        $outpatient_type_time = self::getChooseTime($outpatientTypeTime, 1, 0);// 复诊时间范围

        $pre_arrival_time = self::getChooseTime($preArrivalTime, 1, 1);// 预到时间范围
        $un_arrival_time = self::getChooseTime($unArrivalTime, 0, 2);// 过期未到时间范围
        $sdefaultDate = date("Y-m-d");

        /**
         * 原始条件（备份）
         * $start_time = strtotime(date("Y-m-d 00:00:00"));
         * $end_time = strtotime(date("Y-m-d 23:59:59"));
         * $project_id = $params['project_id'];
         * //当前日期
         * $sdefaultDate = date("Y-m-d");
         * //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期
         * $first = 1;
         * //获取当前周的第几天 周日是 0 周一到周六是 1 - 6
         * $w = date('w', strtotime($sdefaultDate));
         * //获取本周开始日期，如果$w是0，则表示周日，减去 6 天
         * $week_start = date('Y-m-d', strtotime("$sdefaultDate -" . ($w ? $w - $first : 6) . ' days'));
         * $week_start_time = strtotime($week_start);
         * //本周结束日期
         * $week_end_time = date('Y-m-d 23:59:59', strtotime("$week_start +6 days"));*/

        if ($params['customer'] == 1) {
            $next_callback_time = 'kf_next_callback_time';
            $last_revisiting_time = 'last_revisiting_time';
        } else {
            $next_callback_time = 'yz_next_callback_time';
            $last_revisiting_time = 'last_revisiting_time';
        }
        $next_revisiting_time = 'next_revisiting_time';
        $patientQuery = User::find()
            ->select(['id', 'created_at', $next_callback_time, $last_revisiting_time, $next_revisiting_time, 'outpatient_type_id'])
            ->where([
                'and',
                ['project_id' => $project_id],
                ['status' => User::STATUS_ENABLE]
            ]);
        $params['customer'] == 1 ? $patientQuery->andWhere(['belong_member_id' => Yii::$app->user->identity->member_id]) : $patientQuery->andWhere(['belong_assistant_id' => Yii::$app->user->identity->member_id]);
        $patientList = $patientQuery->asArray()
            ->all();
        $list = [
            'count_patient' => count($patientList),
            'today_patient_add' => 0,
            'count_unfollow' => 0,
            'count_unfollow_week' => 0,
            'count_outpatient_type' => 0,
            'count_outpatient_type_week' => 0,
            'count_pre_arrival' => 0,
            'count_pre_arrival_choose' => 0,
            'count_un_arrival_choose' => 0,
            'count_un_arrival' => 0
        ];
        /*$filed = $params['customer'] == 1 ? 'u.belong_member_id' : 'u.belong_assistant_id';
        $count_add_num_query = AllocationRecord::find()
            ->alias('a')
            ->leftJoin(User::tableName() . ' u', 'a.patient_card_id=u.patient_card_id')
            ->select('count(distinct(u.id)) count_num')
            ->where([
                'and',
                ['a.project_id' => $project_id],
                [$filed => Yii::$app->user->identity->member_id],
                ['>=', 'a.created_at', $patient_time['start_time']],
                ['<=', 'a.created_at', $patient_time['end_time']],
            ])
            ->groupBy('u.id');*/
        $count_add_num_query = AllocationRecord::find()
            ->select('count(distinct(patient_card_id)) count_num')
            ->where([
                'and',
                ['project_id' => $project_id],
                ['member_id' => Yii::$app->user->identity->member_id],
                ['>=', 'created_at', $patient_time['start_time']],
                ['<=', 'created_at', $patient_time['end_time']],
            ]);
        $params['customer'] == 1 ? $count_add_num_query->andWhere(['current_profession_id' => 2]) : $count_add_num_query->andWhere(['current_profession_id' => 1]);
        //echo $count_add_num_query->createCommand()->getRawSql();exit;
        $count_add_num = $count_add_num_query->scalar();

        $list['today_patient_add'] = $count_add_num ? $count_add_num : 0;
        $list['today_patient_add_stime'] = date("Y-m-d", $patient_time['start_time']);
        $list['today_patient_add_etime'] = date("Y-m-d", $patient_time['end_time']);
        foreach ($patientList as $value) {
            // 今日新增患者(原版)
            /*if ($value['created_at'] >= $patient_time['start_time'] && $value['created_at'] <= $patient_time['end_time']) {
                $list['today_patient_add']++;
            }*/
            // 总过期未回访数
            if ($value[$next_callback_time] < strtotime($sdefaultDate)) {
                $list['count_unfollow']++;
            }
            $list['count_unfollow_stime'] = date("Y-m-d", $unfollow_time['start_time']);
            $list['count_unfollow_etime'] = date("Y-m-d", $unfollow_time['end_time']);
            // 本周过期未回访数
            if ($value[$next_callback_time] < $unfollow_time['end_time'] && $value[$next_callback_time] >= $unfollow_time['start_time']) {
                $list['count_unfollow_week']++;
            }
            // 总复诊人数
            if ($value['outpatient_type_id'] == Yii::$app->services->statisticsManagementReport::OUTPATIENT_TYPE['referral']) {
                $list['count_outpatient_type']++;
            }
            // 本周总复诊人数
            if ($value['outpatient_type_id'] == Yii::$app->services->statisticsManagementReport::OUTPATIENT_TYPE['referral'] && $value[$last_revisiting_time] >= $outpatient_type_time['start_time'] && $value[$last_revisiting_time] >= $outpatient_type_time['end_time']) {
                $list['count_outpatient_type_week']++;
            }
            $list['count_outpatient_type_stime'] = date("Y-m-d", $outpatient_type_time['start_time']);
            $list['count_outpatient_type_etime'] = date("Y-m-d", $outpatient_type_time['end_time']);
            // 总预到人数
            if ($value[$next_revisiting_time] >= strtotime($sdefaultDate)) {
                $list['count_pre_arrival']++;
            }
            // 范围内预到人数
            if ($value[$next_revisiting_time] >= $pre_arrival_time['start_time'] && $value[$next_revisiting_time] <= $pre_arrival_time['end_time']) {
                $list['count_pre_arrival_choose']++;
            }
            $list['count_pre_arrival_choose_stime'] = date("Y-m-d", $pre_arrival_time['start_time']);
            $list['count_pre_arrival_choose_etime'] = date("Y-m-d", $pre_arrival_time['end_time']);
            // 总过期未到人数
            if ($value[$next_revisiting_time] < strtotime($sdefaultDate)) {
                $list['count_un_arrival']++;
            }
            $list['count_un_arrival_choose_stime'] = date("Y-m-d", $un_arrival_time['start_time']);
            $list['count_un_arrival_choose_etime'] = date("Y-m-d", $un_arrival_time['end_time']);
            // 范围内过期未到人数
            if ($unArrivalTime != 'day') {
                if (strtotime(date("Y-m-d", $un_arrival_time['start_time'])) == strtotime(date("Y-m-d", $un_arrival_time['end_time']))) {
                    $list['count_un_arrival_choose'] = 0;
                } elseif ($value[$next_revisiting_time] >= $un_arrival_time['start_time'] && $value[$next_revisiting_time] <= strtotime(date("Y-m-d 23:59:59", strtotime("-1 days", $un_arrival_time['end_time'])))) {
                    $list['count_un_arrival_choose']++;
                }
            } elseif ($value[$next_revisiting_time] >= $un_arrival_time['start_time'] && $value[$next_revisiting_time] <= $un_arrival_time['end_time']) {
                $list['count_un_arrival_choose']++;
            }
        }

        return $list;
    }

    /**
     * 获取对应时间
     * @param string $type
     * @param int $data_cate 日期状态：1当天，0前一天
     * @param int $data_type 日期类别：1当天及以后，2当天以前
     * @return array
     * @author chenyuebin
     */
    public function getChooseTime(string $type = '', int $data_cate = 0, int $data_type = 0)
    {
        switch ($type) {
            case 'day':
                if ($data_cate == 1) {
                    $start_time = strtotime(date("Y-m-d 00:00:00"));
                    $end_time = strtotime(date("Y-m-d 23:59:59"));
                } else {
                    $start_time = strtotime(date("Y-m-d 00:00:00", strtotime('-1 day')));
                    $end_time = strtotime(date("Y-m-d 23:59:59", strtotime('-1 day')));
                }
                break;
            case 'week':
                //当前日期
                $sdefaultDate = date("Y-m-d");
                //$first =1 表示每周星期一为开始日期 0表示每周日为开始日期
                $first = 1;
                //获取当前周的第几天 周日是 0 周一到周六是 1 - 6
                $w = date('w', strtotime($sdefaultDate));
                //获取本周开始日期，如果$w是0，则表示周日，减去 6 天
                $week_start = date('Y-m-d', strtotime("$sdefaultDate -" . ($w ? $w - $first : 6) . ' days'));
                $week_end = date('Y-m-d 23:59:59', strtotime("$week_start +6 days"));

                if ($data_type == 1) {
                    //本周开始时间
                    $start_time = strtotime(date("Y-m-d"));
                    $end_time = strtotime($week_end);
                } elseif ($data_type == 2) {
                    $start_time = strtotime($week_start);
                    $end_time = strtotime(date("Y-m-d"));
                } else {
                    //本周开始时间
                    $start_time = strtotime($week_start);
                    //本周结束日期
                    $end_time = strtotime($week_end);
                }
                break;
            case 'month':
                $BeginDate = date('Y-m-01', strtotime(date("Y-m-d")));

                if ($data_type == 1) {
                    $start_time = strtotime(date("Y-m-d 00:00:00"));
                    $end_time = strtotime(date('Y-m-d', strtotime("$BeginDate +1 month -1 day")) . ' 23:59:59');
                } elseif ($data_type == 2) {
                    $start_time = strtotime(date("Y-m-01 00:00:00"));
                    $end_time = strtotime(date("Y-m-d 00:00:00"));
                } else {
                    $start_time = strtotime(date("Y-m-01 00:00:00"));
                    $end_time = strtotime(date('Y-m-d', strtotime("$BeginDate +1 month -1 day")) . ' 23:59:59');
                }
                break;
            case 'year':
                if ($data_type == 1) {
                    $start_time = strtotime(date("Y-m-d 00:00:00"));
                    $end_time = strtotime(date("Y-12-31 23:59:59"));
                } elseif ($data_type == 2) {
                    $start_time = strtotime(date("Y-01-01 00:00:00"));
                    $end_time = strtotime(date("Y-m-d 00:00:00"));
                } else {
                    $start_time = strtotime(date("Y-01-01 00:00:00"));
                    $end_time = strtotime(date("Y-12-31 23:59:59"));
                }
                break;
            default:
                if ($data_cate == 1) {
                    $start_time = strtotime(date("Y-m-d 00:00:00"));
                    $end_time = strtotime(date("Y-m-d 23:59:59"));
                } else {
                    $start_time = strtotime(date("Y-m-d 00:00:00", strtotime('-1 day')));
                    $end_time = strtotime(date("Y-m-d 23:59:59", strtotime('-1 day')));
                }
                break;
        }
        return [
            'start_time' => $start_time,
            'end_time' => $end_time
        ];
    }

    public function patientReport(array $params = [])
    {
        $query = User::find()->select([
            'b.effect_name',
            'c.outpatient_name',
            'a.id',
            'a.effect_type_id',
            'a.outpatient_type_id'
        ])
            ->alias('a')
            ->leftJoin(EffectType::tableName() . ' b', 'b.id=a.effect_type_id')
            ->leftJoin(OutpatientType::tableName() . ' c', 'c.id=a.outpatient_type_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => User::STATUS_ENABLE
            ]);
        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $params['project_id'],
        ]);
        // 是否返回客服就诊类型
        $isCustomer = 0;
        if ($attr && $attr->profession_id == Profession::ID_CUSTOMER) {// 客服
            $isCustomer = 1;
        }
        if ($isCustomer == 1) {
            $query->andWhere(['a.belong_member_id' => Yii::$app->user->identity->member_id]);
        } else {
            $query->andWhere(['a.belong_assistant_id' => Yii::$app->user->identity->member_id]);
        }

        $query = $query->asArray()
            ->all();
        $res_effect_type_arr = $this->array_group_by($query, 'effect_name');
        $res_outpatient_type_arr = $this->array_group_by($query, 'outpatient_name');

        // 效果类型
        $effect_type_list = [];
        $effect_data = [];
        $i = 0;
        foreach ($res_effect_type_arr as $key => $value) {
            $effect_type_list[] = $key;
            $effect_data[$i]['name'] = $key;
            $effect_data[$i]['value'] = count($value);
            $i++;
        }

        // 就诊类型
        $outpatient_type_list = [];
        $outpatient_type_data = [];
        foreach ($res_outpatient_type_arr as $key => $value) {
            $outpatient_type_list[] = $key;
            $outpatient_type_data[] = count($value);
        }

        return [
            'effect_type_list' => $effect_type_list,
            'effect_data' => $effect_data,
            'outpatient_type_list' => $outpatient_type_list,
            'outpatient_data' => $outpatient_type_data
        ];
    }

    /**
     * [array_group_by ph]
     * @param  [type] $arr [二维数组]
     * @param  [type] $key [键名]
     * @return [type]      [新的二维数组]
     */
    public function array_group_by($arr, $key)
    {
        $grouped = array();
        foreach ($arr as $value) {
            $grouped[$value[$key]][] = $value;
        }
        if (func_num_args() > 2) {
            $args = func_get_args();
            foreach ($grouped as $key => $value) {
                $parms = array_merge($value, array_slice($args, 2, func_num_args()));
                $grouped[$key] = call_user_func_array('array_group_by', $parms);
            }
        }
        return $grouped;
    }


    /**
     * 关注或取消患者
     *
     * @param int $id
     * @param bool $followStatus
     * @return array
     * @author wangxiang
     */
    public function updatePatientFollow(int $id, bool $followStatus)
    {
        try {

            // 判断患者是否存在
            $flag = User::find()->where(['id' => $id])->exists();
            if (!$flag) {
                return CommonHelper::api(422, '操作失败，患者不存在！');
            }

            if ($followStatus) {
                // 关注患者
                if (!Attention::find()->where(['attention_id' => $id, 'member_id' => Yii::$app->user->identity->member_id])->exists()) {
                    $model = new Attention;
                    $model->member_id = Yii::$app->user->identity->member_id;
                    $model->attention_id = $id;
                    if (!$model->save()) {
                        return CommonHelper::api(422, $model->firstErrors);
                    }
                }
            } else {
                // 取消关注
                Attention::deleteAll(['attention_id' => $id, 'member_id' => Yii::$app->user->identity->member_id]);
            }

            return ['id' => $id];
        } catch (\Exception $e) {
            return CommonHelper::api(422, $e->getMessage());
        }
    }


    /**
     * 根据诊室获取诊室下对应的人员
     *
     * @param int $clinicId
     * @param int $editType 类型，1：客服， 2：医助
     * @param int $projectId
     * @return array
     * @author wangxiang
     */
    public function getMemberByClinicId(int $clinicId, int $editType, int $projectId): array
    {
        $attr = Yii::$app->services->attr->findInfo([
            'member_id' => Yii::$app->user->identity->member_id,
            'project_id' => $projectId,
        ]);
        // 不确定身份， 需要根据当前登录者身份去判断
        if ($editType == 3) {
            if ($attr && $attr->profession_id == Profession::ID_MEDICAL) {// 医助
                $editType = 2;
            } else {
                $editType = 1;
            }
        }

        $condition['project_id'] = $projectId;
        if ($editType == 2) {
            // 医助
            if (!$clinicId) return [];  // 如果没有诊室， 直接返回空
            $condition['clinic_id'] = $clinicId;
            $condition['profession_id'] = Profession::ID_MEDICAL;
        } else {
            $condition['profession_id'] = Profession::ID_CUSTOMER;
        }
        if (Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO) {
            if (!$attr) return [];
            if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_NO) {
                $condition['member_id'] = $attr->member_id;
            } else if ($attr->is_department_leader == Attr::IS_DEPARTMENT_LEADER_YES) {
                $condition['department_id'] = $attr->department_id;
            }
        }

        $attrList = Yii::$app->services->attr->findList($condition);
        $idData = array_column($attrList, 'member_id');

        return Member::find()
            ->where(['id' => $idData, 'status' => Member::STATUS_ENABLE])
            ->select(['id value', 'realname title'])
            ->asArray()
            ->all();
    }

    /**
     * 记录患者更改归属人日志
     *
     * @param int $projectId
     * @param string $patientCardId
     * @param int $memberId
     * @param int $currentProfessionId
     * @throws \Exception
     * @author wangxiang
     */
    public function allocationRecord(int $projectId, string $patientCardId, int $memberId, int $currentProfessionId): void
    {
        $operateId = Yii::$app->user->identity->member_id;
        $model = new AllocationRecord;
        $model->project_id = $projectId;
        $model->patient_card_id = $patientCardId;
        $model->member_id = $memberId;
        $model->current_profession_id = $currentProfessionId;
        $model->operate_id = $operateId;
        if (!$model->save()) {
            throw new \Exception(json_encode($model->errors), 500);
        }
    }

    /**
     * 新增患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getAddListPage(array $params = [], int $page = 0, int $pageSize = 0, int $isReturnTotal = 0)
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE]
            ]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
            if (!isset($params['start_time']) || !$params['start_time'] || !isset($params['end_time']) || !$params['end_time']) {
                $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
            } else {
                $query->innerJoin(AllocationRecord::tableName() . ' AS al', 'al.patient_card_id = a.patient_card_id');
                $query->andWhere(['al.member_id' => $params['member_id']]);
                $query->groupBy('a.patient_card_id');
            }
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
            if (!isset($params['start_time']) || !$params['start_time'] || !isset($params['end_time']) || !$params['end_time']) {
                $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
            } else {
                $query->innerJoin(AllocationRecord::tableName() . ' AS al', 'al.patient_card_id = a.patient_card_id');
                $query->andWhere(['al.member_id' => $params['member_id']]);
                $query->groupBy('a.patient_card_id');
            }
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match)  || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        // 分配开始时间
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'al.created_at', strtotime($params['start_time'])]);
        }

        // 分配结束时间
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'al.created_at', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 总数
        $total = $query->count();
        if ($isReturnTotal == 1) {
            return [
                'total' => (int)$total,
            ];
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            /*if ($type == 2) {// 患者【医助】
                $orderBy = ['a.missed_days' => SORT_DESC];
            } else {
                $orderBy = ['a.updated_at' => SORT_DESC];
            }*/
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query->orderBy($orderBy)->asArray()->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 获取患者总人数
     *
     * @param array $params
     * @return int|string
     */
    public function getAddNum(array $params = [])
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 总数
        return $query->count();
    }

    /**
     * 已到患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getArriveListPage(array $params = [], int $page = 0, int $pageSize = 0, int $checkType = 1, int $isReturnTotal = 0)
    {
        $params['edit_type'] = $params['edit_type'] ?? 0;
        $params['belong_member_id'] = $params['belong_member_id'] ?? 0;
        $params['belong_assistant_id'] = $params['belong_assistant_id'] ?? 0;
        $params['outpatient_type_id'] = $params['outpatient_type_id'] ?? 0;
        $params['project_id'] = Yii::$app->params['project_id'];
        $params['in_hospital'] = $params['in_hospital'] ?? 0;

        // 获取筛选条件
        $type = 0;
        $condition = [];
        if ($checkType == 1) {// 列表初始数据逻辑
            $cparams = [
                'get_customer_member' => 1,
                'get_medical_member' => 1,
                'get_clinic' => 1,
                'get_hospital' => 1,
            ];
            $isCheckType = Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO ? 1 : 0;
            $condition = Yii::$app->services->patientUser->getConditionList($cparams, Yii::$app->params['project_id'], $isCheckType);
            $condition['tags_list'] = CommonService::getTagsList();

            if ($params['edit_type']) {
                $type = $params['edit_type'];
                if ($type == 1) {
                    $params['belong_member_id'] = $params['belong_member_id'] ?: array_column($condition['member_customer_list'], 'id');
                    unset($params['belong_assistant_id']);
                } else {
                    $params['belong_assistant_id'] = $params['belong_assistant_id'] ?: array_column($condition['member_medical_list'], 'id');
                    unset($params['belong_member_id']);
                }
            } else {
                // 当前用户属性
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => Yii::$app->params['project_id'],
                ]);
                $type = 1;
                // 是否返回客服就诊类型
                if ($attr && $attr->profession_id == Profession::ID_CUSTOMER) { // 客服
                    $type = 1;
                    $params['belong_member_id'] = Yii::$app->user->identity->member_id;
                } else {// 医助
                    $type = 2;
                    $params['belong_assistant_id'] = Yii::$app->user->identity->member_id;
                }
            }
            if (isset($params['belong_member_id']) && empty($params['belong_member_id'])) {
                unset($params['belong_member_id']);
            }
            if (isset($params['belong_assistant_id']) && empty($params['belong_assistant_id'])) {
                unset($params['belong_assistant_id']);
            }

            // 获取筛选条件
            $isCustomer = $type == 1 ? 1 : 0;
            $condition1['outpatient_type_list'] = CommonService::getOutpatientTypeList($isCustomer);
            $condition = array_merge($condition, $condition1);
            if (empty($params['outpatient_type_id'])) {
                $params['outpatient_type_id'] = array_column($condition['outpatient_type_list'], 'id');
            }
        }

        // 查询逻辑
        $query = User::find()->alias('a')
            ->select([
                'a.*',
                'ua.in_hospital_status',
                'COUNT(rr.id) revisiting_time_count', 'MAX(rr.revisting_time) revisting_time'
            ])
            ->leftJoin(UserAttr::tableName() . ' ua', 'a.id = ua.patient_user_id')
            ->leftJoin(RevisitingRecord::tableName() . ' rr', 'rr.project_id = a.project_id AND rr.patient_card_id = a.patient_card_id AND rr.is_sum = '.RevisitingRecord::IS_SUM_YES)
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);
        $query->groupBy('a.id');

        // 当前时间>=上次到诊时间
        $query->andWhere(['<=', 'a.last_revisiting_time', Yii::$app->params['time']]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        // 上次到诊开始时间
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'a.last_revisiting_time', strtotime($params['start_time'])]);
            $query->andWhere(['>=', 'rr.revisting_time', strtotime($params['start_time'])]);
        }

        // 上次到诊结束时间
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'a.last_revisiting_time', strtotime($params['end_time'] . ' 23:59:59')]);
            $query->andWhere(['<=', 'rr.revisting_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 门诊
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 是否住院
        if (isset($params['in_hospital']) && $params['in_hospital'] ) {
            if ($params['in_hospital'] == UserAttr::IS_HOSPITAL_YES) {
                $query->andWhere(['ua.in_hospital_status' => UserAttr::STATUS_IN_HOSPITAL]);
            } else {
                $query->andWhere(['ua.in_hospital_status' => [UserAttr::STATUS_NO_HOSPITAL, UserAttr::STATUS_OUT_HOSPITAL]]);
            }
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        $data = $this->getListPageRes($query, $page, $pageSize, $orderBy, $isReturnTotal);
        $data['type'] = $type;
        $data['condition'] = $condition;
        return $data;
    }

    /**
     * 已到患者总数
     *
     * @param array $params
     * @return int|string
     */
    public function getArriveNum(array $params = [])
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 当前时间>=上次到诊时间
        $query->andWhere(['<=', 'a.last_revisiting_time', Yii::$app->params['time']]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 总数
        return $query->count();
    }

    /**
     * 预到患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getOrderArriveListPage(array $params = [], int $page = 0, int $pageSize = 0, int $checkType = 1, int $isReturnTotal = 0)
    {
        $params['edit_type'] = $params['edit_type'] ?? 0;
        $params['belong_member_id'] = $params['belong_member_id'] ?? 0;
        $params['belong_assistant_id'] = $params['belong_assistant_id'] ?? 0;
        $params['outpatient_type_id'] = $params['outpatient_type_id'] ?? 0;
        $params['project_id'] = Yii::$app->params['project_id'];
        $params['in_hospital'] = $params['in_hospital'] ?? 0;

        // 获取筛选条件
        $type = 0;
        $condition = [];
        if ($checkType == 1) {// 列表初始数据逻辑
            $cparams = [
                'get_customer_member' => 1,
                'get_medical_member' => 1,
                'get_clinic' => 1,
                'get_hospital' => 1,
            ];
            $isCheckType = Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO ? 1 : 0;
            $condition = Yii::$app->services->patientUser->getConditionList($cparams, Yii::$app->params['project_id'], $isCheckType);
            $condition['tags_list'] = CommonService::getTagsList();
            if ($params['edit_type']) {
                $type = $params['edit_type'];
                if ($type == 1) {
                    $params['belong_member_id'] = $params['belong_member_id'] ?: array_column($condition['member_customer_list'], 'id');
                    unset($params['belong_assistant_id']);
                } else {
                    $params['belong_assistant_id'] = $params['belong_assistant_id'] ?: array_column($condition['member_medical_list'], 'id');
                    unset($params['belong_member_id']);
                }
            } else {
                // 当前用户属性
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => Yii::$app->params['project_id'],
                ]);
                $type = 1;
                // 是否返回客服就诊类型
                if ($attr && $attr->profession_id == Profession::ID_CUSTOMER) { // 客服
                    $type = 1;
                    $params['belong_member_id'] = Yii::$app->user->identity->member_id;
                } else {// 医助
                    $type = 2;
                    $params['belong_assistant_id'] = Yii::$app->user->identity->member_id;
                }
            }
            if (isset($params['belong_member_id']) && empty($params['belong_member_id'])) {
                unset($params['belong_member_id']);
            }
            if (isset($params['belong_assistant_id']) && empty($params['belong_assistant_id'])) {
                unset($params['belong_assistant_id']);
            }
            // 获取筛选条件
            $isCustomer = $type == 1 ? 1 : 0;
            $condition1['outpatient_type_list'] = CommonService::getOutpatientTypeList($isCustomer);
            $condition = array_merge($condition, $condition1);
            if (empty($params['outpatient_type_id'])) {
                $params['outpatient_type_id'] = array_column($condition['outpatient_type_list'], 'id');
            }
        }

        // 查询逻辑
        $query = User::find()->alias('a')
            ->select([
                'a.*',
                'ua.in_hospital_status',
            ])
            ->leftJoin(UserAttr::tableName() . ' ua', 'a.id = ua.patient_user_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 当前时间<=下次复诊时间
        $query->andWhere(['>=', 'a.next_revisiting_time', strtotime(date('Y-m-d'))]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match)|| preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        // 上次到诊开始时间
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'a.next_revisiting_time', strtotime($params['start_time'])]);
        }

        // 上次到诊结束时间
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'a.next_revisiting_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 门诊
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 是否住院
        if (isset($params['in_hospital']) && $params['in_hospital'] ) {
            if ($params['in_hospital'] == UserAttr::IS_HOSPITAL_YES) {
                $query->andWhere(['ua.in_hospital_status' => UserAttr::STATUS_IN_HOSPITAL]);
            } else {
                $query->andWhere(['ua.in_hospital_status' => [UserAttr::STATUS_NO_HOSPITAL, UserAttr::STATUS_OUT_HOSPITAL]]);
            }
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        $data = $this->getListPageRes($query, $page, $pageSize, $orderBy, $isReturnTotal);
        $data['type'] = $type;
        $data['condition'] = $condition;
        return $data;
    }

    /**
     * 预到患者总数
     *
     * @param array $params
     * @return int|string
     */
    public function getOrderArriveNum(array $params = [])
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 当前时间<=下次复诊时间
        $query->andWhere(['>=', 'a.next_revisiting_time', strtotime(date('Y-m-d'))]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 总数
        return $query->count();
    }

    /**
     * 过期未到患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getUnarriveListPage(array $params = [], int $page = 0, int $pageSize = 0, int $checkType = 1, int $isReturnTotal = 0)
    {
        $params['edit_type'] = $params['edit_type'] ?? 0;
        $params['belong_member_id'] = $params['belong_member_id'] ?? 0;
        $params['belong_assistant_id'] = $params['belong_assistant_id'] ?? 0;
        $params['outpatient_type_id'] = $params['outpatient_type_id'] ?? 0;
        $params['project_id'] = Yii::$app->params['project_id'];
        $params['in_hospital'] = $params['in_hospital'] ?? 0;

        // 获取筛选条件
        $type = 0;
        $condition = [];
        if ($checkType == 1) {// 列表初始数据逻辑
            $cparams = [
                'get_customer_member' => 1,
                'get_medical_member' => 1,
                'get_clinic' => 1,
                'get_hospital' => 1,
            ];
            $isCheckType = Yii::$app->user->identity->member->is_super == Member::IS_SUPER_NO ? 1 : 0;
            $condition = Yii::$app->services->patientUser->getConditionList($cparams, Yii::$app->params['project_id'], $isCheckType);
            $condition['tags_list'] = CommonService::getTagsList();

            if ($params['edit_type']) {
                $type = $params['edit_type'];
                if ($type == 1) {
                    $params['belong_member_id'] = $params['belong_member_id'] ?: array_column($condition['member_customer_list'], 'id');
                    unset($params['belong_assistant_id']);
                } else {
                    $params['belong_assistant_id'] = $params['belong_assistant_id'] ?: array_column($condition['member_medical_list'], 'id');
                    unset($params['belong_member_id']);
                }
            } else {
                // 当前用户属性
                $attr = Yii::$app->services->attr->findInfo([
                    'member_id' => Yii::$app->user->identity->member_id,
                    'project_id' => Yii::$app->params['project_id'],
                ]);
                $type = 1;
                // 是否返回客服就诊类型
                if ($attr && $attr->profession_id == Profession::ID_CUSTOMER) { // 客服
                    $type = 1;
                    $params['belong_member_id'] = Yii::$app->user->identity->member_id;
                } else {// 医助
                    $type = 2;
                    $params['belong_assistant_id'] = Yii::$app->user->identity->member_id;
                }
            }

            if (isset($params['belong_member_id']) && empty($params['belong_member_id'])) {
                unset($params['belong_member_id']);
            }

            if (isset($params['belong_assistant_id']) && empty($params['belong_assistant_id'])) {
                unset($params['belong_assistant_id']);
            }

            // 获取筛选条件
            $isCustomer = $type == 1 ? 1 : 0;
            $condition['outpatient_type_list'] = CommonService::getOutpatientTypeList($isCustomer);
            if (empty($params['outpatient_type_id'])) {
                $params['outpatient_type_id'] = array_column($condition['outpatient_type_list'], 'id');
            }
        }
        
        // 查询逻辑
        $query = User::find()->alias('a')
            ->select([
                'a.*',
                'ua.in_hospital_status',
            ])
            ->leftJoin(UserAttr::tableName() . ' ua', 'a.id = ua.patient_user_id')
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 当前时间>下次复诊时间
        $query->andWhere(['<', 'a.next_revisiting_time', Yii::$app->params['time']]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        // 上次到诊开始时间
        if (isset($params['start_time']) && $params['start_time']) {
            $query->andWhere(['>=', 'a.next_revisiting_time', strtotime($params['start_time'])]);
        }

        // 上次到诊结束时间
        if (!isset($params['end_time']) || empty($params['end_time'])) {
            $endTime = mktime(0, 0, 0, date('m'), date('d') - 1, date('Y'));
            $params['end_time'] = date('Y-m-d', $endTime);
        }
        if (isset($params['end_time']) && $params['end_time']) {
            $query->andWhere(['<=', 'a.next_revisiting_time', strtotime($params['end_time'] . ' 23:59:59')]);
        }

        if ((!isset($params['start_time']) && !isset($params['end_time']))
            || (empty($params['start_time']) && empty($params['start_time']))) {
            $query->andWhere(['>', 'a.next_revisiting_time', 0]);
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 门诊
        if (isset($params['clinic_id']) && $params['clinic_id']) {
            $query->andWhere(['a.clinic_id' => $params['clinic_id']]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 是否住院
        if (isset($params['in_hospital']) && $params['in_hospital'] ) {
            if ($params['in_hospital'] == UserAttr::IS_HOSPITAL_YES) {
                $query->andWhere(['ua.in_hospital_status' => UserAttr::STATUS_IN_HOSPITAL]);
            } else {
                $query->andWhere(['ua.in_hospital_status' => [UserAttr::STATUS_NO_HOSPITAL, UserAttr::STATUS_OUT_HOSPITAL]]);
            }
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        $data = $this->getListPageRes($query, $page, $pageSize, $orderBy, $isReturnTotal);
        $data['type'] = $type;
        $data['condition'] = $condition;
        return $data;
    }

    /**
     * 过期未到患者总数
     *
     * @param array $params
     * @return int|string
     */
    public function getUnarriveNum(array $params = [])
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 当前时间>下次复诊时间
        $query->andWhere(['<', 'a.next_revisiting_time', Yii::$app->params['time']]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 总数
        return $query->count();
    }

    /**
     * 已回访患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getCallbackListPage(array $params = [], int $page = 0, int $pageSize = 0, int $isReturnTotal = 0)
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        /*// 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }*/

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        // 回访记录患者ID
        $data = Yii::$app->services->patientCallback->getCallbackListPage($params);
        $query->andWhere(['a.id' => array_column($data['list'], 'patient_user_id')]);

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 总数
        $total = $query->count();
        if ($isReturnTotal == 1) {
            return [
                'total' => (int)$total,
            ];
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            /*if ($type == 2) {// 患者【医助】
                $orderBy = ['a.missed_days' => SORT_DESC];
            } else {
                $orderBy = ['a.updated_at' => SORT_DESC];
            }*/
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query->orderBy($orderBy)->asArray()->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 过期未回访患者列表
     *
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @param int $isReturnTotal 是否直接返回总数【1是、0否】
     * @return array
     */
    public function getUncallbackListPage(array $params = [], int $page = 0, int $pageSize = 0, int $isReturnTotal = 0)
    {
        $query = User::find()->alias('a')
            ->select([
                'a.*',
            ])
            ->where([
                'a.project_id' => $params['project_id'],
                'a.status' => [User::STATUS_INVALID, User::STATUS_ENABLE],
            ]);

        // 医助归属人
        if (isset($params['belong_assistant_id'])) {
            $query->andWhere(['a.belong_assistant_id' => $params['belong_assistant_id']]);
        }

        // 客服归属人
        if (isset($params['belong_member_id'])) {
            $query->andWhere(['a.belong_member_id' => $params['belong_member_id']]);
        }

        // 关键词
        if (isset($params['keywords']) && $params['keywords']) {
            if (preg_match("/([\x81-\xfe][\x40-\xfe])/", $params['keywords'], $match) || preg_match("/(^[A-Za-z]+$)/",$params['keywords'])) {
                $query->andWhere(['like', 'a.name', "{$params['keywords']}%", false]);
            } else {
                $query->andWhere([
                    'or',
                    ['a.mobile' => trim($params['keywords'])],
                    ['a.patient_card_id' => trim($params['keywords'])],
                ]);
            }
        }

        if (isset($params['belong_member_id'])) {// 客服
            $query->andWhere(['<', 'a.kf_next_callback_time', strtotime(date('Y-m-d'))]);

            // 下次回访开始时间
            if (isset($params['start_time']) && $params['start_time']) {
                $query->andWhere(['>=', 'a.kf_next_callback_time', strtotime($params['start_time'])]);
            }

            // 下次回访结束时间
            if (isset($params['end_time']) && $params['end_time']) {
                $query->andWhere(['<=', 'a.kf_next_callback_time', strtotime($params['end_time'] . ' 23:59:59')]);
            }
        } else {// 医助
            $query->andWhere(['<', 'a.yz_next_callback_time', strtotime(date('Y-m-d'))]);

            // 下次回访开始时间
            if (isset($params['start_time']) && $params['start_time']) {
                $query->andWhere(['>=', 'a.yz_next_callback_time', strtotime($params['start_time'])]);
            }

            // 下次回访结束时间
            if (isset($params['end_time']) && $params['end_time']) {
                $query->andWhere(['<=', 'a.yz_next_callback_time', strtotime($params['end_time'] . ' 23:59:59')]);
            }
        }

        // 就诊类型
        if (isset($params['outpatient_type_id']) && $params['outpatient_type_id']) {
            $query->andWhere(['a.outpatient_type_id' => $params['outpatient_type_id']]);
        }

        // 标签
        if (isset($params['tags_ids']) && $params['tags_ids']) {
            // 患者标签
            $patientTags = Yii::$app->services->patientTags->findList([
                'tags_id' => explode(',', $params['tags_ids']),
                'status' => Tags::STATUS_ENABLE,
            ]);

            // 患者IDs
            $patientUserIds = array_unique(array_column($patientTags, 'patient_user_id'));

            $query->andWhere(['a.id' => $patientUserIds]);
        }

        // 断诊次数
        if (isset($params['fault_diagnosis_type'])) {
            switch ($params['fault_diagnosis_type']) {
                case 1:// 1次
                    $query->andWhere(['a.fault_diagnosis_count' => 1]);
                    break;
                case 2:// 2次
                    $query->andWhere(['a.fault_diagnosis_count' => 2]);
                    break;
                case 3:// 3次
                    $query->andWhere(['a.fault_diagnosis_count' => 3]);
                    break;
                case 4:// 3次以上
                    $query->andWhere(['>=', 'a.fault_diagnosis_count', 4]);
                    break;
                default:
                    break;
            }
        }

        // 总数
        $total = $query->count();
        if ($isReturnTotal == 1) {
            return [
                'total' => (int)$total,
            ];
        }

        // 排序
        $orderBy = [];
        if (isset($params['sort_last_revisiting_type']) && $params['sort_last_revisiting_type']) {// 上次复诊
            if ($params['sort_last_revisiting_type'] == 1) {
                $orderBy = ['a.last_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_last_revisiting_type'] == 2) {
                $orderBy = ['a.last_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_next_revisiting_type']) && $params['sort_next_revisiting_type']) {// 下次复诊
            if ($params['sort_next_revisiting_type'] == 1) {
                $orderBy = ['a.next_revisiting_time' => SORT_ASC];
            } elseif ($params['sort_next_revisiting_type'] == 2) {
                $orderBy = ['a.next_revisiting_time' => SORT_DESC];
            }
        } elseif (isset($params['sort_last_callback_type']) && $params['sort_last_callback_type']) {// 上次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.kf_last_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_last_callback_type'] == 1) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_ASC];
                } elseif ($params['sort_last_callback_type'] == 2) {
                    $orderBy = ['a.yz_last_callback_time' => SORT_DESC];
                }
            }

        } elseif (isset($params['sort_next_callback_type']) && $params['sort_next_callback_type']) {// 下次回访
            if (isset($params['belong_member_id']) && $params['belong_member_id']) {// 客服
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.kf_next_callback_time' => SORT_DESC];
                }
            } else {
                if ($params['sort_next_callback_type'] == 1) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_ASC];
                } elseif ($params['sort_next_callback_type'] == 2) {
                    $orderBy = ['a.yz_next_callback_time' => SORT_DESC];
                }
            }
        } elseif (isset($params['sort_revisiting_type']) && $params['sort_revisiting_type']) {// 复诊次数
            if ($params['sort_revisiting_type'] == 1) {
                $orderBy = ['a.revisiting_count' => SORT_ASC];
            } elseif ($params['sort_revisiting_type'] == 2) {
                $orderBy = ['a.revisiting_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_callback_type']) && $params['sort_callback_type']) {// 回访次数
            if ($params['sort_callback_type'] == 1) {
                $orderBy = ['a.callback_count' => SORT_ASC];
            } elseif ($params['sort_callback_type'] == 2) {
                $orderBy = ['a.callback_count' => SORT_DESC];
            }
        } elseif (isset($params['sort_missed_type']) && $params['sort_missed_type']) {// 未到诊天数
            if ($params['sort_missed_type'] == 1) {
                $orderBy = ['a.missed_days' => SORT_ASC];
            } elseif ($params['sort_missed_type'] == 2) {
                $orderBy = ['a.missed_days' => SORT_DESC];
            }
        } else {
            /*if ($type == 2) {// 患者【医助】
                $orderBy = ['a.missed_days' => SORT_DESC];
            } else {
                $orderBy = ['a.updated_at' => SORT_DESC];
            }*/
            $orderBy = ['a.updated_at' => SORT_DESC];
        }
        $orderBy['a.id'] = SORT_DESC;

        // 分页
        if ($page && $pageSize) {
            $query->limit($pageSize)->offset(($page - 1) * $pageSize);
        }

        $list = $query->orderBy($orderBy)->asArray()->all();

        return [
            'page' => (int)$page,
            'pageSize' => (int)$pageSize,
            'total' => (int)$total,
            'list' => $list,
        ];
    }

    /**
     * 完善患者信息
     * @param array $params
     * @return array|mixed
     * @throws HttpException
     * @author chenyuebin
     */
    public function improvedEdit(array $params)
    {
        // 获取城市
        $city_name = isset($params['city_id']) && $params['city_id'] ? Provinces::find()->select('title')->where(['id' => $params['city_id']])->scalar() : '';
        // 获取部位
        $body_parts = isset($params['body_part_id']) && $params['body_part_id'] ? BaseBodyParts::find()->select('body_parts_name')->where(['in', 'id', array_filter(explode(',', $params['body_part_id']))])->column() : '';
        // 获取患者原信息
        $patient = User::findOne($params['patient_id']);
        if (!$patient) {
            throw new HttpException(422, '未找到该患者信息');
        }
        $oldPatient = new User();
        $oldPatient->setAttributes($patient->getAttributes());

        // 患者标签
        $patient_tags = isset($params['patient_tags_name']) && $params['patient_tags_name'] ? \common\models\marketing\Tags::find()->select(['tags_name'])->where(['id' => array_filter(explode(',', $params['patient_tags_name']))])->column() : '';

        try {
            $transaction = Yii::$app->db->beginTransaction();

            $params['body_parts_ids'] = $params['body_part_id'];
            // 1.更新患者
            $patient->name = $params['name'];
            $patient->gender = $params['gender'];
            $patient->mobile = $params['mobile'];
            $patient->city_id = $params['city_id'];
            $patient->city_name = $city_name;
            $patient->effect_type_id = $params['effect_type_id'];
            $patient->risk_type_id = $params['risk_type_id'];
            $patient->patient_tags_name = $patient_tags ? implode(',', $patient_tags) : '';
            $patient->patient_diseases_id = $params['patient_diseases_id'];
            $patient->patient_body_parts_name = $body_parts ? implode(',', $body_parts) : '';
            $patient->degree_num = $this->computeDegreeNum($params);
            $patient->saveAndCheckResult();

            // 2-2.删除部位
            BodyParts::updateAll(['status' => BodyParts::STATUS_DELETE], ['patient_user_id' => $patient->id]);
            // 2-1.新增部位
            foreach (array_filter(explode(',', $params['body_part_id'])) as $row) {
                $patientBodyParts = new BodyParts();
                $patientBodyParts->patient_user_id = $patient->id;
                $patientBodyParts->body_parts_id = $row;
                $patientBodyParts->status = BodyParts::STATUS_ENABLE;
                $patientBodyParts->save();
            }

            // 3-1.删除患者标签
            Tags::updateAll(['status' => Tags::STATUS_DELETE], ['patient_user_id' => $patient->id]);
            // 3-2 新增标签
            foreach (array_filter(explode(',', $params['patient_tags_name'])) as $tagsVal) {
                $patientTags = new Tags();
                $patientTags->patient_user_id = $patient->id;
                $patientTags->tags_id = $tagsVal;
                $patientTags->status = Tags::STATUS_ENABLE;
                $patientTags->save();
            }

            // 4-1.新增患者操作日志
            PatientOperateLogService::create($params['project_id'], $patient->id, OperateLog::ACTION_TYPE_PATIENT_UPDATE, PatientOperateLogService::getPatientChangeLog($patient, $oldPatient));
            // 4-2.记录手机号编辑历史记录
            PatientHistoryRecordService::create($params['project_id'], $patient->id, HistoryRecord::DATA_TYPE_TEL, $oldPatient->mobile, $patient->mobile);

            $transaction->commit();

            return ['id' => $params['patient_id']];
        } catch (\Exception $e) {
            $transaction->rollBack();

            return CommonHelper::api(422, $e->getMessage());
        }
    }

    /**
     * 同步完善率
     */
    public function synPatientDegreeNum()
    {
        set_time_limit(0);
        ini_set('memory_limit', '2G');

        $userList = $this->findList([
            'select' => ['id', 'patient_tags_name', 'effect_type_id', 'risk_type_id', 'name', 'mobile', 'gender', 'city_id', 'patient_diseases_id', 'patient_body_parts_name AS body_parts_ids']
        ]);

        foreach ($userList as $row) {
            $degreeNum = $this->computeDegreeNum($row);
            User::updateAll(['degree_num' => $degreeNum], ['id' => $row['id']]);

            echo $row['id'] . PHP_EOL;
        }
    }

    /**
     * 计算完善度
     *
     * @param array $param [
     *       'name' => '',// 患者姓名
     *       'mobile' => '',// 患者手机号
     *       'gender' => '',// 性别
     *       'city_id' => '',// 城市
     *       'patient_diseases_id' => '',// 一级病种
     *       'body_parts_ids' => '',// 部位
     * ]
     * @return float 完善度占比
     */
    public function computeDegreeNum(array $param = [])
    {
        // 15%
        $param['name'] = $param['name'] ?? '';
        // 15%
        $param['mobile'] = $param['mobile'] ?? '';
        // 10%
        $param['gender'] = $param['gender'] ?? 0;
        // 10%
        $param['city_id'] = $param['city_id'] ?? 0;
        // 10%
        $param['patient_diseases_id'] = $param['patient_diseases_id'] ?? 0;
        // 10%
        $param['body_parts_ids'] = $param['body_parts_ids'] ?? 0;
        // 10%
        $param['effect_type_id'] = $param['effect_type_id'] ?? 0;
        // 10%
        $param['risk_type_id'] = $param['risk_type_id'] ?? 0;
        // 10%
        $param['patient_tags_name'] = $param['patient_tags_name'] ?? 0;

        $degreeNum = 0.00;
        foreach ($param as $key => $row) {
            if (empty($row)) {
                continue;
            }

            switch ($key) {
                case 'name':// 患者姓名
                    $degreeNum += 0.15;
                    break;
                case 'mobile':// 患者手机号
                    $degreeNum += 0.15;
                    break;
                case 'gender':// 性别
                    $degreeNum += 0.10;
                    break;
                case 'city_id':// 城市
                    $degreeNum += 0.10;
                    break;
                case 'patient_diseases_id':// 一级病种
                    $degreeNum += 0.10;
                    break;
                case 'body_parts_ids':// 部位
                    $degreeNum += 0.10;
                    break;
                case 'effect_type_id':// 效果类型
                    $degreeNum += 0.10;
                    break;
                case 'risk_type_id':// 风控类型ID
                    $degreeNum += 0.10;
                    break;
                case 'patient_tags_name':// 患者标签
                    $degreeNum += 0.10;
                    break;
                default:
                    break;
            }
        }

        return $degreeNum;
    }

    /**
     * 修改下次复诊时间
     *
     * @param $id 患者ID
     * @param $nextRevisitingTime 下次复诊时间
     * @return bool|int
     */
    public function updateNextRevisitingTime($id, $nextRevisitingTime)
    {
        $patientIs = User::findOne(['id' => $id]);
        if ($patientIs->next_revisiting_time != $nextRevisitingTime) {
            return User::updateAll(
                ['next_revisiting_time' => $nextRevisitingTime],
                ['id' => $id]
            );
        }
        return true;
    }

    /**
     * 患者列表tab总数
     * @param int $editType 类型【1客服、2医助】
     * @return array
     */
    public function getTabTotal(int $editType)
    {
        $res = [
            'all_num' => 0,
            'arrive_num' => 0,
            'order_arrive_num' => 0,
            'unarrive_num' => 0,
        ];
        if ($editType == 0) {
            return $res;
        }

        // 全部列表总数
        $allData = $this->getListPage([], 0, 0, $editType, 1);
        /*if ($editType == 1) {// 客服
            $allData = $this->getListPage([], 0, 0, 1, 1);
        } elseif ($editType == 2) {// 医助
            $allData = $this->getListPage([], 0, 0, 2, 1);
        }*/

        // 已到患者总数
        $params = [
            'edit_type' => $editType,
            'start_time' => date('Y-m-d'),
            'end_time' => date('Y-m-d'),
        ];
        $arriveData = $this->getArriveListPage($params, 0, 0, 1, 1);

        // 预到患者总数
        $orderArriveData = $this->getOrderArriveListPage($params, 0, 0, 1, 1);

        // 过期未到患者总数
        $beforeDate = date('Y-m-d', strtotime(date('Y-m-d')) - 86400);
        $params['start_time'] = $beforeDate;
        $params['end_time'] = $beforeDate;
        $unarriveData = $this->getUnarriveListPage($params, 0, 0, 1, 1);

        return [
            'all_num' => $allData['total'],
            'arrive_num' => $arriveData['total'],
            'order_arrive_num' => $orderArriveData['total'],
            'unarrive_num' => $unarriveData['total'],
        ];
    }


    /**
     * 获取患者历史手机号或微信修改记录
     *
     * @param int $patientId
     * @param array $condition
     * @return array
     * @author wangxiang
     */
    public function getHistoryRecord(int $patientId, array $condition)
    {
        $query = HistoryRecord::find()
            ->where([
                'project_id' => $condition['project_id'],
                'patient_user_id' => $patientId
            ]);

        isset($condition['data_type']) && $condition['data_type'] && $query->andWhere(['data_type' => $condition['data_type']]);

        return $query
            ->select(['content'])
            ->orderBy(['updated_at' => SORT_DESC])
            ->column();
    }


    /**
     * 记录患者手机号或微信号修改历史记录
     *
     * @param array $params
     * @throws Exception
     * @author wangxiang
     */
    public function saveHistoryRecord(array $params): void
    {
        if (empty($params['old_content']) || $params['new_content'] == $params['old_content']) {
            return;
        }

        $model = HistoryRecord::findOne([
            'project_id' => $params['project_id'],
            'patient_user_id' => $params['patient_id'],
            'data_type' => $params['data_type'],
            'content' => $params['old_content'],
        ]);
        if (!$model) {
            $model = new HistoryRecord;
            $model->project_id = $params['project_id'];
            $model->patient_user_id = $params['patient_id'];
            $model->data_type = $params['data_type'];
            $model->content = $params['old_content'];
        }
        $model->updated_at = time();
        $model->saveAndCheckResult();

    }

    /**
     * 患者模块的导出
     *
     * @param array $select
     * @param $project_id
     * @param $mudles_name
     * @param array $conditions
     * @return bool
     * @throws HttpException
     * @author chenyuebin
     */
    public function getPatientList($logId, $nameAndPath, array $select, $project_id, $mudles_name, array $conditions = [])
    {
        try {
            $logService = new LogService();
            // 查询的字段
            $selectArr = $logService->selectList($select, $mudles_name);

            $conditionInitArr = [];
            foreach ($conditions as $v) {
                if (isset($v['start_time'])) {
                    $conditionInitArr[$v['id']]['start_time'] = $v['start_time'];
                    $conditionInitArr[$v['id']]['end_time'] = $v['end_time'];
                    $conditionInitArr[$v['id']]['operator'] = $v['operator'];
                } else {
                    $conditionInitArr[$v['id']]['value'] = $v['value'];
                    $conditionInitArr[$v['id']]['operator'] = $v['operator'];
                }
            }

            // 筛选条件
            $conditionArr = $logService->conditionList($conditions, $mudles_name);

            // 获取数据
            $query = User::find()
                ->alias('a')
                ->leftJoin(Member::tableName() . ' b', 'a.belong_assistant_id=b.id')
                ->leftJoin(Clinic::tableName() . ' c', 'a.clinic_id=c.id')
                ->leftJoin(OutpatientType::tableName() . ' d', 'a.outpatient_type_id=d.id')
                ->leftJoin(SourceChannel::tableName() . ' e', 'a.source_channel_id=e.id')
                ->leftJoin(UserTreatment::tableName() . ' f', 'a.patient_card_id=f.patient_card_id')
                ->leftJoin(PatientDiseases::tableName() . ' h', 'a.patient_diseases_id=h.id')
                ->leftJoin(Provinces::tableName() . ' g', 'a.city_id=g.id');

            if ($selectArr) {
                array_push($selectArr, 'a.patient_card_id');
                $query->select($selectArr);
            }

            $query->where(['a.project_id' => $project_id, 'a.status' => User::STATUS_ENABLE]);

            // 传入的查询条件
            if (isset($conditionArr['condition']) && count($conditionArr['condition']) > 1) {
                $query->andWhere($conditionArr['condition']);
            }
            if (isset($conditionArr['tags']) && count($conditionArr['tags']) > 0) {
                foreach ($conditionArr['tags'] as $v) {
                    $query->andWhere(new Expression($v[0]->expression, $v[0]->params));
                }
            }
            // 特殊查询条件处理，目前走原生
            if (isset($conditionArr['other']) && count($conditionArr['other']) > 0) {
                foreach ($conditionArr['other'] as $v) {
                    if (!in_array(ConfigService::CLINIC_TOTAL_NUM, array_keys($conditionInitArr))) {// 如果是统计治疗数量（总计:正常+援助）则忽略此条件，改为走having语句
                        $query->andWhere(new Expression("{$v['condition']['value1']}+{$v['condition']['value2']} {$v['operator']} {$v['value']}"));
                    }
                }
            }

            $query->groupBy('a.id');

            $query->orderBy('f.id desc');
            $data = $query->asArray()->all();


            // 获取患者诊疗号数组集合
            $patientCardIdArr = [];
            foreach ($data as $value) {
                $value['patient_card_id'] = (string)$value['patient_card_id'];
                $patientCardIdArr[] = $value['patient_card_id'];
            }

            $clinicUserTreatQuery = UserTreatment::find()
                ->select([
                    'id',
                    'patient_card_id',
                    'clinic_project_id',
                    'clinic_project_name',
                    'recently_clinic_time',
                    'recently_clinic_num',
                    'recently_surplus_num',
                    'total_num',
                    'help_num',
                    'type',
                ])
                ->where([
                    'project_id' => $project_id,
                    'patient_card_id' => $patientCardIdArr
                ]);
            if (in_array(ConfigService::CLINIC_ID, array_keys($conditionInitArr))) {// 如果筛选项有诊室
                $clinicUserTreatQuery->andWhere(['clinic_id' => $conditionInitArr[ConfigService::CLINIC_ID]['value']]);
            }

            if (in_array(ConfigService::RECENTLY_CLINIC_ID, array_keys($conditionInitArr))) {// 如果筛选项有最近治疗时间
                if ($conditionInitArr[ConfigService::RECENTLY_CLINIC_ID]['operator'] == '=') {
                    $temp1 = [
                        '>=',
                        'recently_clinic_time',
                        strtotime(date("Y-m-d 00:00:00", strtotime($conditionInitArr[ConfigService::RECENTLY_CLINIC_ID]['start_time'])))
                    ];
                    $temp2 = [
                        '<=',
                        'recently_clinic_time',
                        strtotime(date("Y-m-d 23:59:59", strtotime($conditionInitArr[ConfigService::RECENTLY_CLINIC_ID]['end_time'])))
                    ];
                    $clinicUserTreatQuery->andWhere($temp1);
                    $clinicUserTreatQuery->andWhere($temp2);
                } else {
                    $temp1 = [
                        'or',
                        ['<', 'recently_clinic_time', strtotime(date("Y-m-d 00:00:00", strtotime($conditionInitArr[ConfigService::RECENTLY_CLINIC_ID]['start_time'])))],
                        ['>', 'recently_clinic_time', strtotime(date("Y-m-d 23:59:59", strtotime($conditionInitArr[ConfigService::RECENTLY_CLINIC_ID]['end_time'])))]
                    ];
                    $clinicUserTreatQuery->andWhere($temp1);
                }
            }

            if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, array_keys($conditionInitArr))) {// 如果筛选项有治疗项目
                $conditionVal = $conditionInitArr[ConfigService::CLINIC_PROJECT_NAME_ID]['value'];
                $conditionOperator = $conditionInitArr[ConfigService::CLINIC_PROJECT_NAME_ID]['operator'];
                $filed = 'clinic_project_id';
                $clinicUserTreatQuery->andWhere([
                    $conditionOperator,
                    $filed,
                    $conditionVal
                ]);
            }

            $clinicUserTreatment = $clinicUserTreatQuery->asArray()
                ->all();

            // 数据组合处理
            foreach ($data as $key => $value) {
                $value['patient_card_id'] = (string)$value['patient_card_id'];
                if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, array_keys($conditionInitArr))) {// 如果筛选项有治疗项目
                    $data[$key]['clinic_project_id'] = 0;
                }

                if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, $select)) {// 治疗项目
                    $data[$key]['clinic_project_name'] = '';
                }
                if (in_array(ConfigService::HELP_NUM, $select)) {// 本次剩余援助数量
                    $data[$key]['help_num'] = 0;
                }
                if (in_array(ConfigService::TOTAL_NUM, $select)) {// 本次剩余正常数量
                    $data[$key]['total_num'] = 0;
                }
                if (in_array(ConfigService::SY_CLINIC_TOTAL_NUM, $select)) {// 剩余治疗数量（总计:正常+援助）
                    $data[$key]['sy_clinic_total_num'] = 0;
                }
                if (in_array(ConfigService::RECENTLY_CLINIC_NUM, $select) || in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {// 本次治疗 正常数量
                    $data[$key]['recently_clinic_num'] = 0;
                }
                if (in_array(ConfigService::RECENTLY_SURPLUS_NUM, $select) || in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {// 本次治疗 援助数量
                    $data[$key]['recently_surplus_num'] = 0;
                }
                if (in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {// 治疗数量（总计:正常+援助）
                    $data[$key]['clinic_total_num'] = 0;
                }
                $tempClinicProject[$value['patient_card_id']] = [];// 各患者治疗项目id数组
                $totalHelpNumArr[$value['patient_card_id']][] = [];// 剩余治疗数量数组（正常、援助）

                foreach ($clinicUserTreatment as $k => $val) {// 循环治疗数据
                    $val['patient_card_id'] = (string)$val['patient_card_id'];
                    if ($value['patient_card_id'] == $val['patient_card_id']) {
                        // 治疗项目
                        if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, $select)) {
                            if (!in_array($val['clinic_project_name'], $tempClinicProject[$val['patient_card_id']])) {
                                array_push($tempClinicProject[$val['patient_card_id']], $val['clinic_project_name']);
                            }
                            $data[$key]['clinic_project_name'] = implode(',', $tempClinicProject[$val['patient_card_id']]);
                        }

                        // 如果筛选项有治疗项目
                        if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, array_keys($conditionInitArr))) {
                            $data[$key]['clinic_project_id'] = $val['clinic_project_id'];
                        }

                        // 剩余数量数组赋值
                        $totalHelpNumArr[$value['patient_card_id']][$val['clinic_project_id']][$val['id']]['help_num'] = $val['help_num'];
                        $totalHelpNumArr[$value['patient_card_id']][$val['clinic_project_id']][$val['id']]['total_num'] = $val['total_num'];

                        // 本次治疗 正常数量
                        if (in_array(ConfigService::RECENTLY_CLINIC_NUM, $select) || in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {
                            if ($val['type'] == UserTreatment::TYPE_TREAT) {
                                $data[$key]['recently_clinic_num'] += $val['recently_clinic_num'];
                            }
                        }

                        // 本次治疗 援助数量
                        if (in_array(ConfigService::RECENTLY_SURPLUS_NUM, $select) || in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {
                            if ($val['type'] == UserTreatment::TYPE_TREAT) {
                                $data[$key]['recently_surplus_num'] += $val['recently_surplus_num'];
                            }
                        }

                        // 治疗数量（总计:正常+援助）
                        if (in_array(ConfigService::CLINIC_TOTAL_NUM, $select)) {
                            if ($val['type'] == UserTreatment::TYPE_TREAT) {
                                if (!isset($data[$key]['recently_surplus_num'])) {
                                    $recently_surplus_num = 0;
                                } else {
                                    $recently_surplus_num = $data[$key]['recently_surplus_num'];
                                }
                                if (!isset($data[$key]['recently_clinic_num'])) {
                                    $recently_clinic_num = 0;
                                } else {
                                    $recently_clinic_num = $data[$key]['recently_clinic_num'];
                                }
                                $data[$key]['clinic_total_num'] = $recently_surplus_num + $recently_clinic_num;
                            }
                        }
                    }
                }
                if (!in_array(ConfigService::RECENTLY_SURPLUS_NUM, $select)) {
                    unset($data[$key]['recently_surplus_num']);
                }
                if (!in_array(ConfigService::RECENTLY_CLINIC_NUM, $select)) {
                    unset($data[$key]['recently_clinic_num']);
                }

                // 剩余数量相关
                foreach ($totalHelpNumArr as $kTH => $valTH) {
                    $valTH = array_filter($valTH);
                    if ($value['patient_card_id'] == $kTH) {
                        $tempHelpNum = 0;
                        $tempTotalNum = 0;
                        foreach ($valTH as $kTH2 => $valTH2) {
                            krsort($valTH2);
                            $newValTH2 = array_shift($valTH2);

                            $tempHelpNum += $newValTH2['help_num'];
                            $tempTotalNum += $newValTH2['total_num'];
                        }
                        // 本次剩余援助数量
                        if (in_array(ConfigService::HELP_NUM, $select)) {
                            $data[$key]['help_num'] = $tempHelpNum;
                        }
                        // 本次剩余正常数量
                        if (in_array(ConfigService::TOTAL_NUM, $select)) {
                            $data[$key]['total_num'] = $tempTotalNum;
                        }
                        // 剩余治疗数量（总计:正常+援助）
                        if (in_array(ConfigService::SY_CLINIC_TOTAL_NUM, $select)) {
                            $data[$key]['sy_clinic_total_num'] = $tempTotalNum + $tempHelpNum;
                        }
                    }
                }
            }

            foreach ($data as $key => $value) {
                // 如果筛选项有治疗项目
                if (in_array(ConfigService::CLINIC_PROJECT_NAME_ID, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::CLINIC_PROJECT_NAME_ID]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::CLINIC_PROJECT_NAME_ID]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['clinic_project_id'], $conditionOperator, $conditionVal);
                }

                // 如果筛选项有  剩余治疗数量（总计:正常+援助）
                if (in_array(ConfigService::SY_CLINIC_TOTAL_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::SY_CLINIC_TOTAL_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::SY_CLINIC_TOTAL_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['sy_clinic_total_num'], $conditionOperator, $conditionVal);
                }

                // 如果筛选项有  本次剩余正常数量
                if (in_array(ConfigService::TOTAL_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::TOTAL_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::TOTAL_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['total_num'], $conditionOperator, $conditionVal);
                }

                // 如果筛选项有  本次剩余援助数量
                if (in_array(ConfigService::HELP_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::HELP_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::HELP_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['help_num'], $conditionOperator, $conditionVal);
                }

                // 本次治疗 正常数量
                if (in_array(ConfigService::RECENTLY_CLINIC_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::RECENTLY_CLINIC_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::RECENTLY_CLINIC_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['recently_clinic_num'], $conditionOperator, $conditionVal);
                }

                // 本次治疗 援助数量
                if (in_array(ConfigService::RECENTLY_SURPLUS_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::RECENTLY_SURPLUS_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::RECENTLY_SURPLUS_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['recently_surplus_num'], $conditionOperator, $conditionVal);
                }

                // 治疗数量（总计:正常+援助）
                if (in_array(ConfigService::CLINIC_TOTAL_NUM, array_keys($conditionInitArr))) {
                    $conditionVal = $conditionInitArr[ConfigService::CLINIC_TOTAL_NUM]['value'];
                    $conditionOperator = $conditionInitArr[ConfigService::CLINIC_TOTAL_NUM]['operator'];
                    $data = $this->operatorFunc($data, $key, $value['clinic_total_num'], $conditionOperator, $conditionVal);
                }

            }

            $data = $this->dataFormat(array_values($data));

            // 导出的excel  title
            $header = $logService->exportHeaderList($mudles_name, $select);

            // 导出excel字段匹配
            $titleField = $logService->exportFiledList($mudles_name, $select);


            // 执行导出
            if (ExcelHelper::exportDataList($header, $data, $titleField, $nameAndPath['savePath'])) {
                // 导出成功
                $logParams = [
                    'id' => $logId,
                    'down_link' => $nameAndPath['fileName'],
                    'status' => Log::STATUS_SUCCESS,
                    'success_num' => count($data),
                    'failed_num' => 0,
                    'remark' => '导出成功'
                ];
                if (Yii::$app->services->exportLog->updateLog($logParams)) {
                    return true;
                }
            }
        } catch (Exception $exception) {
            // 导出失败
            $logParams = [
                'id' => $logId,
                'down_link' => '',
                'status' => Log::STATUS_FAIL,
                'success_num' => 0,
                'failed_num' => 0,
                'remark' => $exception->getMessage()
            ];
            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }

        return false;

    }

    /**
     * 根据运算符来剔除不符合条件的数据
     *
     * @param $data
     * @param $key
     * @param $value1
     * @param $operator
     * @param $value2
     * @return mixed
     * @author chenyuebin
     */
    public function operatorFunc($data, $key, $value1, $operator, $value2)
    {
        if ($operator == '=') {
            if ($value1 != $value2) {
                unset($data[$key]);
            }
        } elseif ($operator == '!=') {
            if ($value1 == $value2) {
                unset($data[$key]);
            }
        } elseif ($operator == '>') {
            if ($value1 <= $value2) {
                unset($data[$key]);
            }
        } elseif ($operator == '>=') {
            if ($value1 < $value2) {
                unset($data[$key]);
            }
        } elseif ($operator == '<') {
            if ($value1 >= $value2) {
                unset($data[$key]);
            }
        } elseif ($operator == '<=') {
            if ($value1 > $value2) {
                unset($data[$key]);
            }
        }

        return $data;
    }


    /**
     * @apiName 获取
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @param array $select
     * @param array $field
     * @return bool
     * @throws HttpException
     * @author loujie
     */
    public function getPatientUserCardId(array $select, array $field, $logId, $nameAndPath, $project_id)
    {
        $query = User::find()
            ->alias('a')
            ->select([
                'a.patient_card_id',
                'COUNT(rr.id) revisiting_time_count',
            ])
            ->leftJoin(RevisitingRecord::tableName() . ' rr', 'rr.project_id = a.project_id AND rr.patient_card_id = a.patient_card_id AND rr.is_sum = '.RevisitingRecord::IS_SUM_YES)
            ->where([
                'a.status' => User::STATUS_ENABLE,
                'a.project_id' => $project_id
            ]);

        # 1、添加查询条件

        // 挂号日期
        if (isset($select['reg_start']) && !empty($select['reg_start']) && isset($select['reg_end']) && !empty($select['reg_end'])) {
            $query->andWhere(['between', 'a.reg_time', strtotime($select['reg_start']), strtotime($select['reg_end']) + 86399]);
        }

        // 患者状态
        if (isset($select['outpatient_type_id']) && !empty($select['outpatient_type_id'])) {
            $outpatient_type_id = explode(',', $select['outpatient_type_id']);
            $query->andWhere(['a.outpatient_type_id' => $outpatient_type_id]);
        }

        $belongAssistantArray = [];
        $belongMemberArray = [];
        // 处理医助归属人
        if (isset($select['belong_assistant_id']) && !empty($select['belong_assistant_id'])) {
            $belongAssistantArray = explode(',', $select['belong_assistant_id']);
        }
        // 处理客服归属人
        if (isset($select['belong_member_id']) && !empty($select['belong_member_id'])) {
            $belongMemberArray = explode(',', $select['belong_member_id']);
        }
        // 查询客服/医助归属人
        if (!empty($belongAssistantArray) || !empty($belongMemberArray)) {
            $query->andWhere([
                'or',
                !empty($belongAssistantArray) ? ['a.belong_assistant_id' => $belongAssistantArray] : [],
                !empty($belongMemberArray) ? ['a.belong_member_id' => $belongMemberArray] : [],
            ]);
        }

        // 回访次数
        if (isset($select['callback_count_start']) && is_numeric($select['callback_count_start']) && isset($select['callback_count_end']) && is_numeric($select['callback_count_end'])) {
            $query->andWhere([
                'between', 'a.callback_count', $select['callback_count_start'], $select['callback_count_end']
            ]);
        }

        // 未到天数
        if (isset($select['missed_days_start']) && is_numeric($select['missed_days_start']) && isset($select['missed_days_end']) && is_numeric($select['missed_days_end'])) {
            $query->andWhere([
                'between', 'a.missed_days', $select['missed_days_start'], $select['missed_days_end']
            ]);
        }

        // 病种
        if (isset($select['patient_diseases_id']) && !empty($select['patient_diseases_id'])) {
            $patient_diseases_id = explode(',', $select['patient_diseases_id']);
            $query->andWhere(['a.patient_diseases_id' => $patient_diseases_id]);
        }

        // 诊室
        if (isset($select['clinic_id']) && !empty($select['clinic_id'])) {
            $clinic_id = explode(',', $select['clinic_id']);
            $query->andWhere(['a.clinic_id' => $clinic_id]);
        }

        // 复诊次数
        if (isset($select['revisiting_count_start']) && is_numeric($select['revisiting_count_start']) && isset($select['revisiting_count_end']) && is_numeric($select['revisiting_count_end'])) {
            $select['hospital_time_start'] = $select['hospital_time_start'] ?? '';
            $select['hospital_time_end'] = $select['hospital_time_end'] ?? '';
            if (empty($select['hospital_time_start']) || empty($select['hospital_time_end'])) {
                $query->andWhere(['between', 'a.revisiting_count', $select['revisiting_count_start'], $select['revisiting_count_end']]);
            } else {
                $query->having(['between', 'revisiting_time_count', $select['revisiting_count_start'], $select['revisiting_count_end']]);
            }
        }

        // 住院次数 && 住院次数(和查询合并)
        $select_hopital_count = false;
        isset($select['hospital_count_start']) && is_numeric($select['hospital_count_start']) && isset($select['hospital_count_end']) && is_numeric($select['hospital_count_end']) && $select_hopital_count = true;

        if ($select_hopital_count || in_array(ConfigService::IN_HOSPITAL_COUNT, $field)) {
            $query->addSelect('count(c.id) as hospital_count');
            $query->leftJoin(RevisitingRecord::tableName() . ' c', 'c.patient_card_id = a.patient_card_id and c.project_id = ' . $project_id . ' and c.type = ' . RevisitingRecord::TYPE_IN_HOSPITAL);
        }

        // 308 剩余数  && 剩余308治疗数(和查询合并)
        if (isset($select['laser_count_start']) && is_numeric($select['laser_count_start']) && isset($select['laser_count_end']) && is_numeric($select['laser_count_end'])) {
            $clinicProject = Project::find()
                ->select('id')
                ->where([
                    'project_id' => $project_id,
                    'status' => Project::STATUS_ENABLE,
                    'template' => [Project::TEMPLATE_308, Project::TEMPLATE_NAJIN]
                ])->column();
            $res = UserSurplusService::get308List($project_id, $clinicProject, $select);
            $query->andWhere(['a.patient_card_id' => array_column($res, 'patient_card_id')]);
        }

        if (isset($select['hospital_time_start']) && !empty($select['hospital_time_start']) && isset($select['hospital_time_end']) && !empty($select['hospital_time_end']) && $select['hospital_time_type'] == RevisitingRecord::IN_HOSPITAL_NO) {
            $query->andWhere(
                [
                    'or',
                    ['<', 'a.last_revisiting_time', strtotime($select['hospital_time_start'])],
                    ['>', 'a.last_revisiting_time', strtotime($select['hospital_time_end'] . ' 23:59:59')]
                ]
            );
        }

        $query->groupBy('a.patient_card_id');

        # 2. 添加筛选字段
        // 医助归属人
        if (in_array(ConfigService::BELONG_ASSISTANT_ID, $field)) {
            $query->addSelect('a.belong_assistant_id');
        }

        // 客服归属人
        if (in_array(ConfigService::BELONG_MEMBER_ID, $field)) {
            $query->addSelect('a.belong_member_id');
        }

        // 诊室
        if (in_array(ConfigService::CLINIC_ID, $field)) {
            $query->leftJoin(Clinic::tableName() . ' f', 'f.id = a.clinic_id');
            $query->addSelect('f.name as clinic_name');
        }

        // 病种
        if (in_array(ConfigService::PATIENT_DISEASES_ID, $field)) {
            $query->leftJoin(PatientDiseases::tableName() . ' e', 'e.id = a.patient_diseases_id');
            $query->addSelect('e.diseases_name');
        }
        // 二级病种
        if (in_array(ConfigService::PATIENT_CHILD_DISEASES_ID, $field)) {
            $query->leftJoin(PatientDiseases::tableName() . ' e2', 'e2.id = a.patient_diseases_child_id');
            $query->addSelect('e2.diseases_name as diseases_child_name');
        }

        // 上次到诊时间
        if (in_array(ConfigService::LAST_REVISITING_ID, $field)) {
            $query->addSelect(['FROM_UNIXTIME(a.`last_revisiting_time`, "%Y-%m-%d %H：%i" ) last_revisiting_time']);
        }
        // 下次复诊时间
        if (in_array(ConfigService::NEXT_REVISITING_ID, $field)) {
            $query->addSelect(['FROM_UNIXTIME(a.`next_revisiting_time`, "%Y-%m-%d %H：%i" ) next_revisiting_time']);
        }
        // 就诊类型(单独处理)
        if (in_array(ConfigService::OUTPATIENT_TYPE_ID, $field)) {
            $query->addSelect('a.outpatient_type_id');
        }
        // 患者标签
        if (in_array(ConfigService::TAGS_ID, $field)) {
            $query->addSelect('a.patient_tags_name');
        }

        // 复诊次数(来院次数)
        if (in_array(ConfigService::VISITS_ID, $field)) {
            $query->addSelect('a.revisiting_count');
        }
        // 回访次数
        if (in_array(ConfigService::CALLBACK_COUNT_ID, $field)) {
            $query->addSelect('a.callback_count');
        }

        // 客服上次回访时间
        if (in_array(ConfigService::KF_LAST_CALLBACK_ID, $field)) {
            $query->addSelect([
                'FROM_UNIXTIME(a.`kf_last_callback_time`, "%Y-%m-%d %H：%i" ) kf_last_callback_time'
            ]);
        }

        // 医助上次回访时间
        if (in_array(ConfigService::YZ_LAST_CALLBACK_ID, $field)) {
            $query->addSelect([
                'FROM_UNIXTIME(a.`yz_last_callback_time`, "%Y-%m-%d %H：%i" ) yz_last_callback_time'
            ]);
        }

        // 地区
        if (in_array(ConfigService::CITY_NAME_ID, $field)) {
            $query->addSelect('a.city_name');
        }

        // 来源
        if (in_array(ConfigService::SOURCE_CHANNEL_ID, $field)) {
            $query->leftJoin(SourceChannel::tableName() . ' d', 'd.id = a.source_channel_id');
            $query->addSelect('d.source_name');
        }
        // 未到天数
        if (in_array(ConfigService::MISSED_DAYS_ID, $field)) {
            $query->addSelect('a.missed_days');
        }

        // 基本信息 姓名,性别,年龄
        if (in_array(ConfigService::NAME_ID, $field)) {
            $query->addSelect('a.name');
        }
        if (in_array(ConfigService::AGE_ID, $field)) {
            $query->addSelect('a.age');
        }
        if (in_array(ConfigService::GENDER_ID, $field)) {
            $query->addSelect('a.gender');
        }
        // 手机号
        if (in_array(ConfigService::MOBILE_ID, $field)) {
            $query->addSelect('a.mobile');
        }

        // 断诊次数
        if (in_array(ConfigService::FAULT_DIAGNOSIS_COUNT, $field)) {
            $query->addSelect('a.fault_diagnosis_count');
        }

        // 挂号时间
        if (in_array(ConfigService::REG_TIME, $field)) {
            $query->addSelect(['FROM_UNIXTIME(a.reg_time, "%Y-%m-%d %H：%i") as reg_time']);
        }

        // 最近一次回访时间
        $callbackField = '';
        if (in_array(ConfigService::CALLBACK_TIME, $field)) {
            $callbackField .= 'FROM_UNIXTIME(`callback`.`current_callback_time`, "%Y-%m-%d %H：%i" ) AS `current_callback_time`,';
        }
        // 最近一次回访人
        if (in_array(ConfigService::CALLBACK_MEMBER_NAME, $field)) {
            $callbackField .= 'callback.member_name,';
        }
        // 最近一次回访内容
        if (in_array(ConfigService::CALLBACK_CONTENT, $field)) {
            $callbackField .= 'callback.content';
        }
        if ($callbackField) {
            $query->leftJoin(Callback::tableName() . ' callback', 'callback.patient_user_id=a.id AND callback.id in (SELECT MAX(callback2.id) from ' . Callback::tableName() . ' as callback2  group by callback2.patient_user_id)');
            $query->addSelect($callbackField);
        }
        
        $data = $query->asArray()->all();
        $patientCardArray = array_column($data, 'patient_card_id');


        // 指定日期来院  /  未来院
        if (isset($select['hospital_time_start']) && !empty($select['hospital_time_start']) && isset($select['hospital_time_end']) && !empty($select['hospital_time_end'])) {
            // 筛选类型(十分难搞,稍后想咋搞)
            $inHospital = RevisitingRecord::find()
                ->select('patient_card_id')
                ->where([
                    'and',
                    ['project_id' => $project_id],
                    ['is_sum' => RevisitingRecord::IS_SUM_YES],
                    ['patient_card_id' => $patientCardArray],
                ])
                ->andWhere([
                    'and',
                    ['between', 'revisting_time', strtotime($select['hospital_time_start']), strtotime($select['hospital_time_end']) + 86399]
                ])
                ->groupBy('patient_card_id')
                ->column();

            if (isset($select['hospital_time_type']) && $select['hospital_time_type'] == RevisitingRecord::IN_HOSPITAL_YES) {
                $patientCardArray = $inHospital;
            } /*else {
                // 未来院 取差集
                $patientCardArray = array_diff($patientCardArray, $inHospital);
            }*/
        }

        // 住院次数(结果集中筛选)
        if ($select_hopital_count) {
            $query->andWhere(['between', 'hospital_count', $select['hospital_count_start'], $select['hospital_count_end']]);
            $s = $select['hospital_count_start'];
            $e = $select['hospital_count_end'];
            $data = array_filter($data, function ($v) use ($s, $e) {
                return $v['hospital_count'] >= $s && $v['hospital_count'] <= $e;
            });
        }
        $dealData = $this->patientFormat($data, $patientCardArray, $field, $select, $project_id);

        $logService = new LogService();

        // 导出excel字段匹配
        $titleField = $logService->exportFiledList(ConfigService::GENERAL_ID, $field);
        $header = $logService->exportHeaderList(ConfigService::GENERAL_ID, $field);


        // 执行导出
        if (ExcelHelper::exportDataDeal($header, $dealData, $titleField, $nameAndPath['savePath'])) {
            // 导出成功
            $logParams = [
                'id' => $logId,
                'down_link' => $nameAndPath['fileName'],
                'status' => Log::STATUS_SUCCESS,
                'success_num' => count($dealData),
                'failed_num' => 0,
                'remark' => '导出成功'
            ];
            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }
    }

    /**
     * @apiName 导出数据的格式处理
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @param $data
     * @param $patientCardArray
     * @param $field
     * @param $select
     * @param $project_id
     * @return array
     * @author loujie
     */
    public function patientFormat($data, $patientCardArray, $field, $select, $project_id)
    {
        $patientArray = array_column($data, null, 'patient_card_id');
        unset($data);

        // 只有存在指定时间来院,才会获取
        $dealData = [];
        $start_time = null;
        $end_time = null;

        if (isset($select['hospital_time_start']) && !empty($select['hospital_time_start']) && isset($select['hospital_time_end']) && !empty($select['hospital_time_end'])) {
            if (isset($select['hospital_time_type']) && $select['hospital_time_type'] == RevisitingRecord::IN_HOSPITAL_YES) {
                $start_time = strtotime($select['hospital_time_start']);
                $end_time = strtotime($select['hospital_time_end']);
            }
        }

        if (in_array(ConfigService::ALL_MONEY, $field)) {
            // 统计所有消费记录总和
            $consumptionMoney = $this->consumptionAllMoney($patientCardArray, $start_time, $end_time, $project_id);
        }

        // 308 治疗/购买
        if (in_array(ConfigService::TREAT_308, $field) || in_array(ConfigService::BUY_308, $field)) {
            $clinicProject = Project::find()
                ->select('id')
                ->where([
                    'project_id' => $project_id,
                    'status' => Project::STATUS_ENABLE,
                    'template' => [Project::TEMPLATE_308, Project::TEMPLATE_NAJIN]
                ])->column();
            $treatmentArray = $this->treatment($patientCardArray, $start_time, $end_time, $clinicProject, $project_id);
        }

        // 归属人信息
        if (in_array(ConfigService::BELONG_ASSISTANT_ID, $field) || in_array(ConfigService::BELONG_MEMBER_ID, $field)) {
            $memberArray = Member::find()
                ->select('m.id, m.realname')
                ->alias('m')
                ->leftJoin(Attr::tableName() . ' a', 'a.member_id = m.id')
                ->where([
                    'a.project_id' => $project_id,
                ])
                ->asArray()
                ->all();

            $memberArray = array_column($memberArray, 'realname', 'id');
        }

        // 308剩余数
        if (in_array(ConfigService::SURPLUS_308, $field)) {
            $clinicProject = Project::find()
                ->select('id')
                ->where([
                    'project_id' => $project_id,
                    'status' => Project::STATUS_ENABLE,
                    'template' => [Project::TEMPLATE_308, Project::TEMPLATE_NAJIN]
                ])->column();
            $userSurplusList = UserSurplusService::get308List($project_id, $clinicProject, $select);
        }

        foreach ($patientCardArray as $patient_card_id) {
            unset($temp);

            if (isset($patientArray[$patient_card_id])) {
                $temp = $patientArray[$patient_card_id];
            } else {
                continue;
            }

            // 消费总额(单独查询)
            if (in_array(ConfigService::ALL_MONEY, $field)) {
                $temp['money'] = $consumptionMoney[$patient_card_id] ?? 0;
            }

            $temp['patient_card_id'] = (string)$temp['patient_card_id'];

            // 治疗308个数(单独查询)
            if (in_array(ConfigService::TREAT_308, $field)) {
                $temp['308_treat'] = isset($treatmentArray[$patient_card_id]) ? $treatmentArray[$patient_card_id]['treat_count'] : 0;
            }

            // 308购买个数(单独查询)
            if (in_array(ConfigService::BUY_308, $field)) {
                $temp['308_buy'] = isset($treatmentArray[$patient_card_id]) ? $treatmentArray[$patient_card_id]['buy_count'] - $treatmentArray[$patient_card_id]['reduce_count'] : 0;
            }

            // 客服归属人
            if (in_array(ConfigService::BELONG_ASSISTANT_ID, $field)) {
                $temp['belong_assistant_name'] = $memberArray[$temp['belong_assistant_id']] ?? '';
            }

            // 医助归属人
            if (in_array(ConfigService::BELONG_MEMBER_ID, $field)) {
                $temp['belong_member_name'] = $memberArray[$temp['belong_member_id']] ?? '';
            }

            if (in_array(ConfigService::OUTPATIENT_TYPE_ID, $field)) {
                $temp['outpatient_type_name'] = OutpatientType::$outpatientType[$temp['outpatient_type_id']];
            }

            if (in_array(ConfigService::GENDER_ID, $field)) {
                $temp['gender'] = User::$genders[$temp['gender']];
            }

            // 复诊次数(来院次数)
            if (in_array(ConfigService::VISITS_ID, $field)) {
                if (isset($temp['revisiting_time_count'])) {
                    $temp['revisiting_count'] = $temp['revisiting_time_count'];
                    unset($temp['revisiting_time_count']);
                }
            }

            // 剩余308数
            if (in_array(ConfigService::SURPLUS_308, $field)) {
                $temp['308_count'] = $userSurplusList[$patient_card_id]['308_count'] ?? 0;
            }

            unset($patientArray[$patient_card_id]);
            $dealData[] = $temp;
        }

        return $dealData;
    }

    /**
     * @apiName 统计指定时间内的消费记录
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @param $patientCardArray
     * @param $start_time
     * @param $end_time
     * @return array|\yii\db\ActiveRecord[]
     * @author loujie
     */
    public function consumptionAllMoney($patientCardArray, $start_time, $end_time, $project_id)
    {
        $query = Consumption::find()
            ->select('patient_card_id,sum(reality_money) as money')
            ->where([
                'project_id' => $project_id,
                'patient_card_id' => $patientCardArray
            ]);

        if (!empty($start_time) && !empty($end_time)) {
            $query->andWhere(['between', 'clinic_time', $start_time, $end_time]);
        }

        $query->groupBy('patient_card_id');
        $moneyArray = $query->asArray()->all();
        $moneyArray = array_column($moneyArray, 'money', 'patient_card_id');

        return $moneyArray;
    }

    /**
     * @apiName 用户308 指定时间内的 治疗/购买数量
     * @apiGroup
     * @apiParam {Number}
     * @apiParam {String}
     * @param $patientCardArray 患者卡号
     * @param $start_time
     * @param $end_time
     * @param $clinic_project_id 需要查询的治疗项目
     * @param $project_id
     * @return array|\yii\db\ActiveRecord[]
     * @author loujie
     */
    public function treatment($patientCardArray, $start_time, $end_time, $clinic_project_id, $project_id)
    {
        $query = UserTreatment::find()
            ->select([
                'patient_card_id',
                'sum(
                    case when type = ' . UserTreatment::TYPE_TREAT . '
                         then recently_clinic_num + recently_surplus_num
                         else 0
                         end
                ) as treat_count',
                'sum(
                    case when type = ' . UserTreatment::TYPE_ADD . '
                         then recently_clinic_num + recently_surplus_num
                         else 0
                         end
                ) as buy_count',
                'sum(
                    case when type = ' . UserTreatment::TYPE_REDUCE . '
                         then recently_clinic_num + recently_surplus_num
                         else 0
                         end
                ) as reduce_count'
            ])
            ->where([
                'project_id' => $project_id,
                'patient_card_id' => $patientCardArray,
            ]);

        !empty($clinic_project_id) && $query->andWhere(['clinic_project_id' => $clinic_project_id]);

        if (!empty($start_time) && !empty($end_time)) {
            $query->andWhere(['between', 'recently_clinic_time', $start_time, $end_time]);
        }

        $query->groupBy('patient_card_id');
        $treatmentsArray = $query->asArray()->all();
        $treatmentsArray = array_column($treatmentsArray, null, 'patient_card_id');
        return $treatmentsArray;
    }


    /**
     * 导医模块数据导出
     *
     * @param $handle
     * @param array $select
     * @param $project_id
     * @param $mudles_name
     * @param array $conditions
     * @return bool
     * @throws HttpException
     * @author chenyuebin
     */
    public function getMedicalList($logId, $nameAndPath, array $select, $project_id, $mudles_name, array $conditions = [])
    {
        try {
            $logService = new LogService();
            // 查询的字段
            $selectArr = $logService->selectList($select, $mudles_name);
            // 筛选条件
            $conditionArr = $logService->conditionList($conditions, $mudles_name);
            // 获取数据
            $query = User::find()
                ->alias('a')
                ->leftJoin(Clinic::tableName() . ' b', 'a.clinic_id=b.id')
                ->leftJoin(PatientDiseases::tableName() . ' c', 'a.patient_diseases_id=c.id')
                ->leftJoin(SourceChannel::tableName() . ' d', 'a.source_channel_id=d.id')
                ->leftJoin(Provinces::tableName() . ' e', 'a.city_id=e.id');

            if ($selectArr) {
//            if (in_array('c.diseases_name',$selectArr))
                $query->select($selectArr);
            }

            $query->where(['a.project_id' => $project_id, 'a.status' => User::STATUS_ENABLE]);
            // 传入的查询条件
            if (isset($conditionArr['condition']) && count($conditionArr['condition']) > 1) {
                $query->andWhere($conditionArr['condition']);
            }
            if (isset($conditionArr['tags']) && count($conditionArr['tags']) > 0) {
                foreach ($conditionArr['tags'] as $v) {
                    $query->andWhere(new Expression($v[0]->expression, $v[0]->params));
                }
            }
            $query->groupBy('a.id');
            $data = $query->asArray()->all();
            $data = $this->dataFormat($data);
            // 导出的excel  title
            $header = $logService->exportHeaderList($mudles_name, $select);

            // 导出excel字段匹配
            $titleField = $logService->exportFiledList($mudles_name, $select);

            // 执行导出
            if (ExcelHelper::exportDataList($header, $data, $titleField, $nameAndPath['savePath'])) {
                // 导出成功
                $logParams = [
                    'id' => $logId,
                    'down_link' => $nameAndPath['fileName'],
                    'status' => Log::STATUS_SUCCESS,
                    'success_num' => count($data),
                    'failed_num' => 0,
                    'remark' => '导出成功'
                ];
                if (Yii::$app->services->exportLog->updateLog($logParams)) {
                    return true;
                }
            }
        } catch (Exception $exception) {
            // 导出失败
            $logParams = [
                'id' => $logId,
                'down_link' => '',
                'status' => Log::STATUS_FAIL,
                'success_num' => 0,
                'failed_num' => 0,
                'remark' => $exception->getMessage()
            ];
            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 回访模块数据导出
     *
     * @param $handle
     * @param array $select
     * @param $project_id
     * @param $mudles_name
     * @param array $conditions
     * @return bool
     * @throws HttpException
     * @author chenyuebin
     */
    public function getCallbackList($logId, $nameAndPath, array $select, $project_id, $mudles_name, array $conditions = [])
    {
        try {
            $logService = new LogService();
            // 查询的字段
            $selectArr = $logService->selectList($select, $mudles_name);
            // 筛选条件
            $conditionArr = $logService->conditionList($conditions, $mudles_name);

            // 获取数据
            $query = User::find()
                ->alias('a')
                ->leftJoin(Member::tableName() . ' b', 'a.belong_assistant_id=b.id')
                ->leftJoin(Clinic::tableName() . ' c', 'a.clinic_id=c.id')
                ->leftJoin(OutpatientType::tableName() . ' d', 'a.outpatient_type_id=d.id')
                ->leftJoin(SourceChannel::tableName() . ' e', 'a.source_channel_id=e.id')
                ->leftJoin(Callback::tableName() . ' f', 'a.id=f.patient_user_id')
                ->leftJoin(Provinces::tableName() . ' h', 'a.city_id=h.id');

            if ($selectArr) {
                foreach ($selectArr as $k => $v) {
                    if ($v == 'f.content') {
                        $selectArr[$k] = ' group_concat(f.content) content ';
                    }
                }
                $query->select($selectArr);
            }

            $query->where(['a.project_id' => $project_id, 'a.status' => User::STATUS_ENABLE, 'f.status' => Callback::STATUS_ENABLE]);
            // 传入的查询条件
            if (isset($conditionArr['condition']) && count($conditionArr['condition']) > 1) {
                $query->andWhere($conditionArr['condition']);
            }
            if (isset($conditionArr['tags']) && count($conditionArr['tags']) > 0) {
                foreach ($conditionArr['tags'] as $v) {
                    $query->andWhere(new Expression($v[0]->expression, $v[0]->params));
                }
            }
            $query->groupBy('a.id');

            $data = $query->asArray()->all();
            $data = $this->dataFormat($data);

            // 导出的excel  title
            $header = $logService->exportHeaderList($mudles_name, $select);

            // 导出excel字段匹配
            $titleField = $logService->exportFiledList($mudles_name, $select);

            // 执行导出
            if (ExcelHelper::exportDataList($header, $data, $titleField, $nameAndPath['savePath'])) {
                // 导出成功
                $logParams = [
                    'id' => $logId,
                    'down_link' => $nameAndPath['fileName'],
                    'status' => Log::STATUS_SUCCESS,
                    'success_num' => count($data),
                    'failed_num' => 0,
                    'remark' => '导出成功'
                ];
                if (Yii::$app->services->exportLog->updateLog($logParams)) {
                    return true;
                }
            }
        } catch (Exception $exception) {
            // 导出失败
            $logParams = [
                'id' => $logId,
                'down_link' => '',
                'status' => Log::STATUS_FAIL,
                'success_num' => 0,
                'failed_num' => 0,
                'remark' => $exception->getMessage()
            ];
            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 消费模块数据导出
     *
     * @param $handle
     * @param array $select
     * @param $project_id
     * @param $mudles_name
     * @param array $conditions
     * @return bool
     * @throws HttpException
     * @author chenyuebin
     */
    public function getConsumptionList($logId, $nameAndPath, array $select, $project_id, $mudles_name, array $conditions = [])
    {
        try {
            $logService = new LogService();
            // 查询的字段
            $selectArr = $logService->selectList($select, $mudles_name);
            // 筛选条件
            $conditionArr = $logService->conditionList($conditions, $mudles_name);

            // 获取数据
            $query = Consumption::find()
                ->alias('a')
                ->leftJoin(User::tableName() . ' b', 'a.patient_card_id=b.patient_card_id and a.project_id=b.project_id');

            if ($selectArr) {
                array_push($selectArr, 'a.refund_money');
                $query->select($selectArr);
            }

            $query->where(['a.project_id' => $project_id, 'b.status' => User::STATUS_ENABLE]);
            // 传入的查询条件
            if (isset($conditionArr['condition']) && count($conditionArr['condition']) > 1) {
                $query->andWhere($conditionArr['condition']);
            }
            if (isset($conditionArr['tags']) && count($conditionArr['tags']) > 0) {
                foreach ($conditionArr['tags'] as $v) {
                    $query->andWhere(new Expression($v[0]->expression, $v[0]->params));
                }
            }
            $query->groupBy('b.id');
            $data = $query->asArray()->all();
            $data = $this->dataFormat($data);
            // 导出的excel  title
            $header = $logService->exportHeaderList($mudles_name, $select);

            // 导出excel字段匹配
            $titleField = $logService->exportFiledList($mudles_name, $select);

            // 执行导出
            if (ExcelHelper::exportDataList($header, $data, $titleField, $nameAndPath['savePath'])) {
                // 导出成功
                $logParams = [
                    'id' => $logId,
                    'down_link' => $nameAndPath['fileName'],
                    'status' => Log::STATUS_SUCCESS,
                    'success_num' => count($data),
                    'failed_num' => 0,
                    'remark' => '导出成功'
                ];
                if (Yii::$app->services->exportLog->updateLog($logParams)) {
                    return true;
                }
            }

            return false;
        } catch (Exception $exception) {
            // 导出失败
            $logParams = [
                'id' => $logId,
                'down_link' => '',
                'status' => Log::STATUS_FAIL,
                'success_num' => 0,
                'failed_num' => 0,
                'remark' => $exception->getMessage()
            ];
            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 治疗模块数据导出
     *
     * @param $handle
     * @param array $select
     * @param $project_id
     * @param $mudles_name
     * @param array $conditions
     * @return bool
     * @throws HttpException
     * @author chenyuebin
     */
    public function getTreatmentExportList($logId, $nameAndPath, array $select, $project_id, $mudles_name, array $conditions = [])
    {
        try {
            $logService = new LogService();
            // 查询的字段
            $selectArr = $logService->selectList($select, $mudles_name);
            // 筛选条件
            $conditionArr = $logService->conditionList($conditions, $mudles_name);

            // 获取数据
            $query = UserTreatment::find()
                ->alias('b')
                ->leftJoin(User::tableName() . ' a', 'a.patient_card_id=b.patient_card_id and a.project_id=b.project_id');

            if ($selectArr) {
                $query->select($selectArr);
            }
            $query->where(['a.project_id' => $project_id, 'a.status' => User::STATUS_ENABLE]);
            // 传入的查询条件
            if (isset($conditionArr['condition']) && count($conditionArr['condition']) > 1) {
                $query->andWhere($conditionArr['condition']);
            }
            // 特殊查询条件处理，目前走原生
            if (isset($conditionArr['other']) && count($conditionArr['other']) > 0) {
                foreach ($conditionArr['other'] as $v) {
                    $query->andWhere(new Expression("{$v['condition']['value1']}+{$v['condition']['value2']} {$v['operator']} {$v['value']}"));
                }
            }
            if (isset($conditionArr['tags']) && count($conditionArr['tags']) > 0) {
                foreach ($conditionArr['tags'] as $v) {
                    $query->andWhere(new Expression($v[0]->expression, $v[0]->params));
                }
            }
            $query->groupBy('a.id');

            $data = $query->asArray()->all();
            $data = $this->dataFormat($data);

            // 导出的excel  title
            $header = $logService->exportHeaderList($mudles_name, $select);

            // 导出excel字段匹配
            $titleField = $logService->exportFiledList($mudles_name, $select);

            // 执行导出
            if (ExcelHelper::exportDataList($header, $data, $titleField, $nameAndPath['savePath'])) {
                // 导出成功
                $logParams = [
                    'id' => $logId,
                    'down_link' => $nameAndPath['fileName'],
                    'status' => Log::STATUS_SUCCESS,
                    'success_num' => count($data),
                    'failed_num' => 0,
                    'remark' => '导出成功'
                ];
                if (Yii::$app->services->exportLog->updateLog($logParams)) {
                    return true;
                }
            }
        } catch (Exception $exception) {
            // 导出失败
            $logParams = [
                'id' => $logId,
                'down_link' => '',
                'status' => Log::STATUS_FAIL,
                'success_num' => 0,
                'failed_num' => 0,
                'remark' => $exception->getMessage()
            ];

            if (Yii::$app->services->exportLog->updateLog($logParams)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 格式化数据中的参数
     *
     * @param $data
     * @return mixed
     * @author chenyuebin
     */
    public function dataFormat($data)
    {
        foreach ($data as $key => $value) {
            if (isset($value['gender']) && $value['gender'] >= 0) {
                $data[$key]['gender'] = User::$genders[$value['gender']];
            }
            if (isset($value['last_revisiting_time']) && $value['last_revisiting_time']) {
                $data[$key]['last_revisiting_time'] = date("Y-m-d H:i:s", $value['last_revisiting_time']);
            }
            if (isset($value['next_revisiting_time']) && $value['next_revisiting_time']) {
                $data[$key]['next_revisiting_time'] = date("Y-m-d H:i:s", $value['next_revisiting_time']);
            }
            if (isset($value['kf_last_callback_time']) && $value['kf_last_callback_time']) {
                $data[$key]['kf_last_callback_time'] = date("Y-m-d H:i:s", $value['kf_last_callback_time']);
            }
            if (isset($value['yz_last_callback_time']) && $value['yz_last_callback_time']) {
                $data[$key]['yz_last_callback_time'] = date("Y-m-d H:i:s", $value['yz_last_callback_time']);
            }
            if (isset($value['kf_next_callback_time']) && $value['kf_next_callback_time']) {
                $data[$key]['kf_next_callback_time'] = date("Y-m-d H:i:s", $value['kf_next_callback_time']);
            }
            if (isset($value['yz_next_callback_time']) && $value['yz_next_callback_time']) {
                $data[$key]['yz_next_callback_time'] = date("Y-m-d H:i:s", $value['yz_next_callback_time']);
            }
            /*if (isset($value['created_at'])) {
                $data[$key]['created_at'] = date("Y-m-d H:i:s", $value['clinic_time']);
            }*/
            if (isset($value['recently_clinic_time'])) {
                $data[$key]['recently_clinic_time'] = date("Y-m-d H:i:s", $value['recently_clinic_time']);
            }
            if (isset($value['clinic_time'])) {
                $data[$key]['clinic_time'] = date("Y-m-d H:i:s", $value['clinic_time']);
            }
            if (isset($value['created_at'])) {
                $data[$key]['created_at'] = date("Y-m-d H:i:s", $value['created_at']);
            }
            if (isset($value['trade_type'])) {
                $data[$key]['trade_type'] = Consumption::TRADE_TYPE[$value['trade_type']];
            }
            if (isset($value['content'])) {
                $content = explode(',', $value['content']);
                $data[$key]['content'] = $content[count($content) - 1];
            }

            // 如果有二级病种则获取二级病种，否则获取一级病种
            if (isset($value['patient_diseases_child_id']) && $value['patient_diseases_child_id']) {
                $diseases = Yii::$app->services->patientDiseases->findById($value['patient_diseases_child_id']);
                $data[$key]['diseases_name'] = $diseases->diseases_name ? $diseases->diseases_name : $data[$key]['diseases_name'];
            }
        }

        return $data;
    }

    /**
     * 同步患者部位
     */
    public function synPatientBody()
    {
        set_time_limit(0);
        ini_set('memory_limit', '2G');

        $patientBodyList = BodyParts::find()->alias('a')
            ->select(['a.*'])
            ->innerJoin(\common\models\base\BodyParts::tableName() . ' AS b', 'b.id = a.body_parts_id')
            ->where([
                'b.type' => \common\models\base\BodyParts::TYPE_NORMAL,
            ])
            ->asArray()
            ->all();

        // 删除部位列表【保留业务部位】
        BodyParts::deleteAll(['body_parts_id' => array_column($patientBodyList, 'body_parts_id')]);

        // 重置部位列表名称
        User::updateAll(['patient_body_parts_name' => '']);

        // 业务部位
        $patientBusinessBodyList = BodyParts::find()->alias('a')
            ->select([
                'a.patient_user_id',
                'GROUP_CONCAT(b.body_parts_name) AS patient_body_parts_name'
            ])
            ->innerJoin(\common\models\base\BodyParts::tableName() . ' AS b', 'b.id = a.body_parts_id')
            ->where([
                'a.status' => BodyParts::STATUS_ENABLE,
                'b.type' => \common\models\base\BodyParts::TYPE_BUSINESS,
            ])
            ->groupBy('a.patient_user_id')
            ->asArray()
            ->all();

        foreach ($patientBusinessBodyList as $row) {
            User::updateAll(['patient_body_parts_name' => $row['patient_body_parts_name']], ['id' => $row['patient_user_id']]);

            echo $row['patient_user_id'] . PHP_EOL;
        }
    }

    /**
     * 导医登记患者
     * @param $params
     * @return int
     * @throws HttpException
     * @author chenyuebin
     */
    public function patientAdd($params)
    {
        $transaction = Yii::$app->db->beginTransaction();
        try {
            // 随机获取医助id
            $medical_member_id_list = Attr::find()->alias('a')
                ->select('a.member_id')
                ->innerJoin(Member::tableName().' m', 'm.id = a.member_id')
                ->where([
                    'a.project_id' => $params['project_id'],
                    'a.profession_id' => 301,
                    'a.clinic_id' => $params['clinic_id'],
                    'm.status' => Member::STATUS_ENABLE,
                ])
                ->column();

            $randNum = rand(0, count($medical_member_id_list));
            if ($randNum == count($medical_member_id_list)) {
                $randNum = 0;
            }
            $medical_member_id_list = array_unique($medical_member_id_list);
            $medical_member_id = $medical_member_id_list ? $medical_member_id_list[$randNum] : 0;

            $patientUser = new User();
            $patientUser->name = $params['user_name'];
            $patientUser->gender = (int)$params['gender'];
            $patientUser->project_id = $params['project_id'];
            $patientUser->reg_time = time();// 初诊日期
            $patientUser->last_revisiting_time = time();// 上次到诊日期
            $patientUser->outpatient_type_id = 1000;// 初诊
            $patientUser->belong_assistant_id = $medical_member_id;
            // 完善度参数
            $DegreeNumArr = [
                'name' => $params['user_name'],
                'gender' => $params['gender'],
            ];
            if (isset($params['mobile']) && $params['mobile']) {
                $DegreeNumArr['mobile'] = $params['mobile'];// 完善度
                $patientUser->mobile = $params['mobile'];
            }
            if (isset($params['wx_name']) && $params['wx_name']) {
                $patientUser->wx_name = $params['wx_name'];
            }
            $patientUser->patient_card_id = $params['patient_card_id'];
            $patientUser->clinic_id = $params['clinic_id'];
            if (isset($params['birthday']) && $params['birthday']) {
                $patientUser->birthday = $params['birthday'];
            }
            if (isset($params['age']) && $params['age']) {
                $patientUser->age = $params['age'];
            }
            if (isset($params['source_channel_id']) && $params['source_channel_id']) {
                $patientUser->source_channel_id = $params['source_channel_id'];
            }
            if (isset($params['city_id']) && (int)$params['city_id'] > 0) {
                $DegreeNumArr['city_id'] = $params['city_id'];// 完善度
                $patientUser->city_id = (int)$params['city_id'];
                $cityInfo = Yii::$app->services->provinces->findById((int)$params['city_id']);
                $patientUser->city_name = $cityInfo->title;
            }
            if (isset($params['remark']) && $params['remark']) {
                $patientUser->remark = $params['remark'];
            }
            // 完善度
            $patientUser->degree_num = $this->computeDegreeNum($DegreeNumArr);
            $patientUser->saveAndCheckResult();

            // 添加操作日志
            PatientOperateLogService::create($params['project_id'], $patientUser->id, OperateLog::ACTION_TYPE_PATIENT_CREATE, '新增患者|' . $patientUser->name);
            // 用户全局日志
            MemberOperateLogService::createGuideLog('guide_craete', $patientUser);

            $transaction->commit();

            return $patientUser->id;
        } catch (Exception $exception) {
            $transaction->rollBack();

            throw new HttpException(422, $exception->getMessage());
        }
    }

    /**
     * 诊疗号检测
     *
     * @param $project_id
     * @param $patient_card_id
     * @return bool
     * @author chenyuebin
     */
    public function patientCardCheck($project_id, $patient_card_id)
    {
        return User::find()
            ->where([
                'project_id' => $project_id,
                'patient_card_id' => $patient_card_id
            ])
            ->exists();
    }

    public function getPatientListByReg(array $params): array
    {
        $query = User::find()
            ->alias('a')
            ->leftJoin(Project::tableName() . ' b', 'a.project_id = b.id')
            ->select($params['column'])
            ->where([
                'and',
                ['>=', 'a.reg_time', $params['start_time']],
                ['<=', 'a.reg_time', $params['end_time']],
            ])
            ->andWhere(['a.status' => User::STATUS_ENABLE]);

        if ($params['type'] == 1) {
            $query->andWhere(['!=', 'a.mobile', '']);
        } elseif ($params['type'] == 2) {
            $query->andWhere(['!=', 'a.wx_name', '']);
        } else {
            $query->andWhere(['!=', 'a.name', '']);
        }

        if (isset($params['project_id']) && $params['project_id']) {
            $query->andWhere(['a.project_id' => $params['project_id']]);
        }

        return $query->asArray()->all();
    }

    public function getPatientArriveList(array $params): array
    {
        // 白友已到患者
//        $patient_card_id_arr = $params['patient_card_id_arr'];// 诊疗号
//        $project_id_arr = $params['relation_baiyou_pname'];// 白友简称

        $query = User::find()
            ->alias('a')
            ->leftJoin(BaseProject::tableName() . ' p', 'a.project_id=p.id')
            ->leftJoin(Tags::tableName() . ' pt', 'a.id=pt.patient_user_id')
            ->select('a.reg_time,a.project_id,p.name_sx,age,gender,patient_diseases_id,patient_diseases_child_id,city_name,patient_card_id,reg_time,group_concat(distinct pt.tags_id) tags_id');
        if (isset($params['patient_card_id_arr']) && $params['patient_card_id_arr']) {
            $query->where([
                'a.patient_card_id' => $params['patient_card_id_arr'],
            ]);
        }
        if (isset($params['relation_baiyou_pname']) && $params['relation_baiyou_pname']) {
            $query->andWhere([
                'p.name_sx' => array_unique($params['relation_baiyou_pname']),
            ]);
        }
        $project_id = $params['project_id'];
        $patient_card_id = $params['patient_card_id'];
        $matching = $params['matching'];
        if (!$project_id && !$patient_card_id && !$matching) {
            $query->andWhere([
                'and',
                ['>=', 'reg_time', $params['start_time']],
                ['<=', 'reg_time', $params['end_time']],
            ]);
        }
        if ($project_id) {
            $query->andWhere(['a.project_id' => $project_id]);
        }

        return $query->groupBy('a.id')
            ->asArray()
            ->all();
    }
}
